1 /* HP Scanjet 3900 series - RTS8822 Core
2 
3    Copyright (C) 2005-2013 Jonathan Bravo Lopez <jkdsoft@gmail.com>
4 
5    This file is part of the SANE package.
6 
7    This program is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License
9    as published by the Free Software Foundation; either version 2
10    of the License, or (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <https://www.gnu.org/licenses/>.
19 
20    As a special exception, the authors of SANE give permission for
21    additional uses of the libraries contained in this release of SANE.
22 
23    The exception is that, if you link a SANE library with other files
24    to produce an executable, this does not by itself cause the
25    resulting executable to be covered by the GNU General Public
26    License.  Your use of that executable is in no way restricted on
27    account of linking the SANE library code into it.
28 
29    This exception does not, however, invalidate any other reasons why
30    the executable file might be covered by the GNU General Public
31    License.
32 
33    If you submit changes to SANE to the maintainers to be included in
34    a subsequent release, you agree by submitting the changes that
35    those changes may be distributed with this exception intact.
36 
37    If you write modifications of your own for SANE, it is your choice
38    whether to permit this exception to apply to your modifications.
39    If you do not wish that, delete this exception notice.
40 */
41 
42 
43 /*
44  This code is still a bit ugly due to it's the result of applying
45  reverse engineering techniques to windows driver. So at this
46  moment what you see is exactly what windows driver does.
47  And so many global vars exist that will be erased when driver
48  is entirely debugged. There are some variables with unknown
49  purpose. So they have no meaning name in form v+address. I
50  hope to change their names when driver is debugged completely.
51 */
52 
53 #ifndef RTS8822_CORE
54 
55 #define RTS8822_CORE
56 
57 #define GetTickCount() (time(0) * 1000)
58 #define min(A,B) (((A)<(B)) ? (A) : (B))
59 #define max(A,B) (((A)>(B)) ? (A) : (B))
60 #define PIXEL_TO_MM(_pixel_, _dpi_) ((_pixel_) * 25.4 / (_dpi_))
61 #define MM_TO_PIXEL(_mm_, _dpi_) ((_mm_) * (_dpi_) / 25.4)
62 
63 #include <stdio.h>
64 #include <stdlib.h>
65 #include <string.h>		/* memset()   */
66 #include <time.h>		/* clock()   */
67 #include <math.h>		/* truncf()  */
68 #include <ctype.h>		/* tolower() */
69 #include <unistd.h>		/* usleep()  */
70 #include <sys/types.h>
71 
72 #include "hp3900_types.c"
73 #include "hp3900_debug.c"
74 #include "hp3900_config.c"
75 #include "hp3900_usb.c"
76 
77 /*-------------------- Exported function headers --------------------*/
78 
79 #ifdef developing
80 static SANE_Int hp4370_prueba (struct st_device *dev);
81 static void prueba (SANE_Byte * a);
82 void shadingtest1 (struct st_device *dev, SANE_Byte * Regs,
83 		   struct st_calibration *myCalib);
84 static SANE_Int Calib_test (struct st_device *dev, SANE_Byte * Regs,
85 			    struct st_calibration *myCalib,
86 			    struct st_scanparams *scancfg);
87 static SANE_Int Calib_BlackShading_jkd (struct st_device *dev,
88 					SANE_Byte * Regs,
89 					struct st_calibration *myCalib,
90 					struct st_scanparams *scancfg);
91 #endif
92 
93 /*static void show_diff(struct st_device *dev, SANE_Byte *original);*/
94 
95 /* functions to allocate and free space for a device */
96 static struct st_device *RTS_Alloc (void);
97 static void RTS_Free (struct st_device *dev);
98 
99 /* Scanner level commands */
100 static SANE_Int RTS_Scanner_Init (struct st_device *dev);
101 static SANE_Int RTS_Scanner_SetParams (struct st_device *dev,
102 				       struct params *param);
103 static SANE_Int RTS_Scanner_StartScan (struct st_device *dev);
104 static void RTS_Scanner_StopScan (struct st_device *dev, SANE_Int wait);
105 static void RTS_Scanner_End (struct st_device *dev);
106 
107 /* loading configuration functions */
108 static SANE_Int Load_Buttons (struct st_device *dev);
109 static SANE_Int Load_Chipset (struct st_device *dev);
110 static SANE_Int Load_Config (struct st_device *dev);
111 static SANE_Int Load_Constrains (struct st_device *dev);
112 static SANE_Int Load_Motor (struct st_device *dev);
113 static SANE_Int Load_MotorCurves (struct st_device *dev);
114 static SANE_Int Load_Motormoves (struct st_device *dev);
115 static SANE_Int Load_Scanmodes (struct st_device *dev);
116 static SANE_Int Load_Sensor (struct st_device *dev);
117 static SANE_Int Load_Timings (struct st_device *dev);
118 
119 /* freeing configuration functions */
120 static void Free_Buttons (struct st_device *dev);
121 static void Free_Chipset (struct st_device *dev);
122 static void Free_Config (struct st_device *dev);
123 static void Free_Constrains (struct st_device *dev);
124 static void Free_Motor (struct st_device *dev);
125 static void Free_MotorCurves (struct st_device *dev);
126 static void Free_Motormoves (struct st_device *dev);
127 static void Free_Scanmodes (struct st_device *dev);
128 static void Free_Sensor (struct st_device *dev);
129 static void Free_Timings (struct st_device *dev);
130 static void Free_Vars (void);
131 
132 /* Functions to manage data */
133 static SANE_Byte data_bitget (SANE_Byte * address, SANE_Int mask);
134 static void data_bitset (SANE_Byte * address, SANE_Int mask, SANE_Byte data);
135 static SANE_Int data_lsb_get (SANE_Byte * address, SANE_Int size);
136 static void data_lsb_set (SANE_Byte * address, SANE_Int data, SANE_Int size);
137 static void data_msb_set (SANE_Byte * address, SANE_Int data, SANE_Int size);
138 static void data_wide_bitset (SANE_Byte * address, SANE_Int mask,
139 			      SANE_Int data);
140 static SANE_Int data_swap_endianess (SANE_Int address, SANE_Int size);
141 
142 static SANE_Int Device_get (SANE_Int product, SANE_Int vendor);
143 
144 /* Chipset related commands */
145 static SANE_Int Chipset_ID (struct st_device *dev);
146 static SANE_Int Chipset_Name (struct st_device *dev, char *name,
147 			      SANE_Int size);
148 static SANE_Int Chipset_Reset (struct st_device *dev);
149 
150 /* Initializing functions */
151 static SANE_Int Init_Registers (struct st_device *dev);
152 static SANE_Int Init_USBData (struct st_device *dev);
153 static SANE_Int Init_Vars (void);
154 
155 /* scanmode functions */
156 static SANE_Int Scanmode_fitres (struct st_device *dev, SANE_Int scantype,
157 				 SANE_Int colormode, SANE_Int resolution);
158 static SANE_Int Scanmode_maxres (struct st_device *dev, SANE_Int scantype,
159 				 SANE_Int colormode);
160 static SANE_Int Scanmode_minres (struct st_device *dev, SANE_Int scantype,
161 				 SANE_Int colormode);
162 
163 /* Chipset management useful commands*/
164 static SANE_Int RTS_USBType (struct st_device *dev);
165 static SANE_Byte RTS_Sensor_Type (USB_Handle usb_handle);
166 static void RTS_DebugInit (void);
167 static SANE_Int RTS_Enable_CCD (struct st_device *dev, SANE_Byte * Regs,
168 				SANE_Int channels);
169 
170 /* DMA management commands */
171 static SANE_Int RTS_DMA_Cancel (struct st_device *dev);
172 static SANE_Int RTS_DMA_CheckType (struct st_device *dev, SANE_Byte * Regs);
173 static SANE_Int RTS_DMA_Enable_Read (struct st_device *dev, SANE_Int dmacs,
174 				     SANE_Int size, SANE_Int options);
175 static SANE_Int RTS_DMA_Enable_Write (struct st_device *dev, SANE_Int dmacs,
176 				      SANE_Int size, SANE_Int options);
177 static SANE_Int RTS_DMA_Read (struct st_device *dev, SANE_Int dmacs,
178 			      SANE_Int options, SANE_Int size,
179 			      SANE_Byte * buffer);
180 static SANE_Int RTS_DMA_Reset (struct st_device *dev);
181 static SANE_Int RTS_DMA_SetType (struct st_device *dev, SANE_Byte * Regs,
182 				 SANE_Byte ramtype);
183 static SANE_Int RTS_DMA_WaitReady (struct st_device *dev, SANE_Int msecs);
184 static SANE_Int RTS_DMA_Write (struct st_device *dev, SANE_Int dmacs,
185 			       SANE_Int options, SANE_Int size,
186 			       SANE_Byte * buffer);
187 
188 /* EEPROM management commands */
189 static SANE_Int RTS_EEPROM_ReadByte (USB_Handle usb_handle, SANE_Int address,
190 				     SANE_Byte * data);
191 static SANE_Int RTS_EEPROM_ReadInteger (USB_Handle usb_handle,
192 					SANE_Int address, SANE_Int * data);
193 static SANE_Int RTS_EEPROM_ReadWord (USB_Handle usb_handle, SANE_Int address,
194 				     SANE_Int * data);
195 static SANE_Int RTS_EEPROM_WriteBuffer (USB_Handle usb_handle,
196 					SANE_Int address, SANE_Byte * data,
197 					SANE_Int size);
198 static SANE_Int RTS_EEPROM_WriteByte (USB_Handle usb_handle, SANE_Int address,
199 				      SANE_Byte data);
200 static SANE_Int RTS_EEPROM_WriteInteger (USB_Handle usb_handle,
201 					 SANE_Int address, SANE_Int data);
202 static SANE_Int RTS_EEPROM_WriteWord (USB_Handle usb_handle, SANE_Int address,
203 				      SANE_Int data);
204 
205 static SANE_Int RTS_Execute (struct st_device *dev);
206 static SANE_Int RTS_Warm_Reset (struct st_device *dev);
207 static SANE_Byte RTS_IsExecuting (struct st_device *dev, SANE_Byte * Regs);
208 
209 static SANE_Int RTS_GetScanmode (struct st_device *dev, SANE_Int scantype,
210 				 SANE_Int colormode, SANE_Int resolution);
211 static SANE_Int RTS_GetImage (struct st_device *dev, SANE_Byte * Regs,
212 			      struct st_scanparams *scancfg,
213 			      struct st_gain_offset *gain_offset,
214 			      SANE_Byte * buffer,
215 			      struct st_calibration *myCalib,
216 			      SANE_Int options, SANE_Int gainmode);
217 static SANE_Int RTS_GetImage_GetBuffer (struct st_device *dev, double dSize,
218 					SANE_Byte * buffer,
219 					double *transferred);
220 static SANE_Int RTS_GetImage_Read (struct st_device *dev, SANE_Byte * buffer,
221 				   struct st_scanparams *myvar,
222 				   struct st_hwdconfig *hwdcfg);
223 
224 static SANE_Int RTS_isTmaAttached (struct st_device *dev);
225 
226 /* functions to wait for a process tp finish */
227 static SANE_Int RTS_WaitInitEnd (struct st_device *dev, SANE_Int msecs);
228 static SANE_Int RTS_WaitScanEnd (struct st_device *dev, SANE_Int msecs);
229 
230 /* functions to read/write control registers */
231 static SANE_Int RTS_ReadRegs (USB_Handle usb_handle, SANE_Byte * buffer);
232 static SANE_Int RTS_WriteRegs (USB_Handle usb_handle, SANE_Byte * buffer);
233 
234 /* functions to manage the scan counter */
235 static SANE_Int RTS_ScanCounter_Inc (struct st_device *dev);
236 static SANE_Int RTS_ScanCounter_Get (struct st_device *dev);
237 
238 /* functions to setup control registers */
239 static SANE_Int RTS_Setup (struct st_device *dev, SANE_Byte * Regs,
240 			   struct st_scanparams *myvar,
241 			   struct st_hwdconfig *hwdcfg,
242 			   struct st_gain_offset *gain_offset);
243 static void RTS_Setup_Arrangeline (struct st_device *dev,
244 				   struct st_hwdconfig *hwdcfg,
245 				   SANE_Int colormode);
246 static void RTS_Setup_Channels (struct st_device *dev, SANE_Byte * Regs,
247 				struct st_scanparams *scancfg,
248 				SANE_Int mycolormode);
249 static void RTS_Setup_Coords (SANE_Byte * Regs, SANE_Int iLeft, SANE_Int iTop,
250 			      SANE_Int width, SANE_Int height);
251 static SANE_Int RTS_Setup_Depth (SANE_Byte * Regs,
252 				 struct st_scanparams *scancfg,
253 				 SANE_Int mycolormode);
254 static void RTS_Setup_Exposure_Times (SANE_Byte * Regs,
255 				      struct st_scanparams *scancfg,
256 				      struct st_scanmode *sm);
257 static void RTS_Setup_GainOffset (SANE_Byte * Regs,
258 				  struct st_gain_offset *gain_offset);
259 static void RTS_Setup_Gamma (SANE_Byte * Regs, struct st_hwdconfig *lowcfg);
260 static SANE_Int RTS_Setup_Line_Distances (struct st_device *dev,
261 					  SANE_Byte * Regs,
262 					  struct st_scanparams *scancfg,
263 					  struct st_hwdconfig *hwdcfg,
264 					  SANE_Int mycolormode,
265 					  SANE_Int arrangeline);
266 static SANE_Int RTS_Setup_Motor (struct st_device *dev, SANE_Byte * Regs,
267 				 struct st_scanparams *myvar,
268 				 SANE_Int somevalue);
269 static void RTS_Setup_RefVoltages (struct st_device *dev, SANE_Byte * Regs);
270 static void RTS_Setup_SensorTiming (struct st_device *dev, SANE_Int mytiming,
271 				    SANE_Byte * Regs);
272 static void RTS_Setup_Shading (SANE_Byte * Regs,
273 			       struct st_scanparams *scancfg,
274 			       struct st_hwdconfig *hwdcfg,
275 			       SANE_Int bytes_per_line);
276 
277 static SANE_Int Scan_Start (struct st_device *dev);
278 
279 static void SetLock (USB_Handle usb_handle, SANE_Byte * Regs,
280 		     SANE_Byte Enable);
281 static SANE_Int fn3330 (struct st_device *dev, SANE_Byte * Regs,
282 			struct st_cal2 *calbuffers,
283 			SANE_Int sensorchannelcolor, SANE_Int * tablepos,
284 			SANE_Int data);
285 static SANE_Int fn3560 (USHORT * table, struct st_cal2 *calbuffers,
286 			SANE_Int * tablepos);
287 static SANE_Int fn3730 (struct st_device *dev, struct st_cal2 *calbuffers,
288 			SANE_Byte * Regs, USHORT * table,
289 			SANE_Int sensorchannelcolor, SANE_Int data);
290 
291 static SANE_Int Reading_CreateBuffers (struct st_device *dev);
292 static SANE_Int Reading_DestroyBuffers (struct st_device *dev);
293 static SANE_Int Reading_BufferSize_Get (struct st_device *dev,
294 					SANE_Byte channels_per_dot,
295 					SANE_Int channel_size);
296 static SANE_Int Reading_BufferSize_Notify (struct st_device *dev,
297 					   SANE_Int data, SANE_Int size);
298 static SANE_Int Reading_Wait (struct st_device *dev,
299 			      SANE_Byte Channels_per_dot,
300 			      SANE_Byte Channel_size, SANE_Int size,
301 			      SANE_Int * last_amount, SANE_Int seconds,
302 			      SANE_Byte op);
303 
304 static SANE_Int Read_Image (struct st_device *dev, SANE_Int buffer_size,
305 			    SANE_Byte * buffer, SANE_Int * transferred);
306 static SANE_Int Read_ResizeBlock (struct st_device *dev, SANE_Byte * buffer,
307 				  SANE_Int buffer_size,
308 				  SANE_Int * transferred);
309 static SANE_Int Read_Block (struct st_device *dev, SANE_Int buffer_size,
310 			    SANE_Byte * buffer, SANE_Int * transferred);
311 static SANE_Int Read_NonColor_Block (struct st_device *dev,
312 				     SANE_Byte * buffer, SANE_Int buffer_size,
313 				     SANE_Byte ColorMode,
314 				     SANE_Int * transferred);
315 
316 /* Ref functions */
317 static SANE_Int Refs_Analyze_Pattern (struct st_scanparams *scancfg,
318 				      SANE_Byte * scanned_pattern,
319 				      SANE_Int * ler1, SANE_Int ler1order,
320 				      SANE_Int * ser1, SANE_Int ser1order);
321 static SANE_Int Refs_Counter_Inc (struct st_device *dev);
322 static SANE_Byte Refs_Counter_Load (struct st_device *dev);
323 static SANE_Int Refs_Counter_Save (struct st_device *dev, SANE_Byte data);
324 static SANE_Int Refs_Detect (struct st_device *dev, SANE_Byte * Regs,
325 			     SANE_Int resolution_x, SANE_Int resolution_y,
326 			     SANE_Int * x, SANE_Int * y);
327 static SANE_Int Refs_Load (struct st_device *dev, SANE_Int * x, SANE_Int * y);
328 static SANE_Int Refs_Save (struct st_device *dev, SANE_Int left_leading,
329 			   SANE_Int start_pos);
330 static SANE_Int Refs_Set (struct st_device *dev, SANE_Byte * Regs,
331 			  struct st_scanparams *myscan);
332 
333 /* Coordinates' constrains functions */
334 static SANE_Int Constrains_Check (struct st_device *dev, SANE_Int Resolution,
335 				  SANE_Int scantype,
336 				  struct st_coords *mycoords);
337 static struct st_coords *Constrains_Get (struct st_device *dev,
338 					 SANE_Byte scantype);
339 
340 /* Gain and offset functions */
341 static SANE_Int GainOffset_Clear (struct st_device *dev);
342 static SANE_Int GainOffset_Get (struct st_device *dev);
343 static SANE_Int GainOffset_Save (struct st_device *dev, SANE_Int * offset,
344 				 SANE_Byte * gain);
345 static SANE_Int GainOffset_Counter_Inc (struct st_device *dev,
346 					SANE_Int * arg1);
347 static SANE_Byte GainOffset_Counter_Load (struct st_device *dev);
348 static SANE_Int GainOffset_Counter_Save (struct st_device *dev,
349 					 SANE_Byte data);
350 
351 /* Gamma functions*/
352 static SANE_Int Gamma_AllocTable (SANE_Byte * table);
353 static SANE_Int Gamma_Apply (struct st_device *dev, SANE_Byte * Regs,
354 			     struct st_scanparams *scancfg,
355 			     struct st_hwdconfig *hwdcfg,
356 			     struct st_gammatables *mygamma);
357 static void Gamma_FreeTables (void);
358 static SANE_Int Gamma_SendTables (struct st_device *dev, SANE_Byte * Regs,
359 				  SANE_Byte * gammatable, SANE_Int size);
360 static SANE_Int Gamma_GetTables (struct st_device *dev,
361 				 SANE_Byte * Gamma_buffer);
362 
363 /* Lamp functions */
364 static SANE_Byte Lamp_GetGainMode (struct st_device *dev, SANE_Int resolution,
365 				   SANE_Byte scantype);
366 static void Lamp_SetGainMode (struct st_device *dev, SANE_Byte * Regs,
367 			      SANE_Int resolution, SANE_Byte gainmode);
368 static SANE_Int Lamp_PWM_DutyCycle_Get (struct st_device *dev,
369 					SANE_Int * data);
370 static SANE_Int Lamp_PWM_DutyCycle_Set (struct st_device *dev,
371 					SANE_Int duty_cycle);
372 static SANE_Int Lamp_PWM_Setup (struct st_device *dev, SANE_Int lamp);
373 static SANE_Int Lamp_PWM_use (struct st_device *dev, SANE_Int enable);
374 static SANE_Int Lamp_PWM_CheckStable (struct st_device *dev,
375 				      SANE_Int resolution, SANE_Int lamp);
376 static SANE_Int Lamp_PWM_Save (struct st_device *dev, SANE_Int fixedpwm);
377 static SANE_Int Lamp_PWM_SaveStatus (struct st_device *dev, SANE_Byte status);
378 static SANE_Int Lamp_Status_Get (struct st_device *dev, SANE_Byte * flb_lamp,
379 				 SANE_Byte * tma_lamp);
380 static SANE_Int Lamp_Status_Set (struct st_device *dev, SANE_Byte * Regs,
381 				 SANE_Int turn_on, SANE_Int lamp);
382 static SANE_Int Lamp_Status_Timer_Set (struct st_device *dev,
383 				       SANE_Int minutes);
384 static SANE_Int Lamp_Warmup (struct st_device *dev, SANE_Byte * Regs,
385 			     SANE_Int lamp, SANE_Int resolution);
386 
387 /* Head related functions */
388 static SANE_Int Head_IsAtHome (struct st_device *dev, SANE_Byte * Regs);
389 static SANE_Int Head_ParkHome (struct st_device *dev, SANE_Int bWait,
390 			       SANE_Int movement);
391 static SANE_Int Head_Relocate (struct st_device *dev, SANE_Int speed,
392 			       SANE_Int direction, SANE_Int ypos);
393 
394 /* Motor functions */
395 static SANE_Byte *Motor_AddStep (SANE_Byte * steps, SANE_Int * bwriten,
396 				 SANE_Int step);
397 static SANE_Int Motor_Change (struct st_device *dev, SANE_Byte * buffer,
398 			      SANE_Byte value);
399 static SANE_Int Motor_GetFromResolution (SANE_Int resolution);
400 static SANE_Int Motor_Move (struct st_device *dev, SANE_Byte * Regs,
401 			    struct st_motormove *mymotor,
402 			    struct st_motorpos *mtrpos);
403 static void Motor_Release (struct st_device *dev);
404 static SANE_Int Motor_Setup_Steps (struct st_device *dev, SANE_Byte * Regs,
405 				   SANE_Int mysetting);
406 static SANE_Int Motor_Curve_Equal (struct st_device *dev,
407 				   SANE_Int motorsetting, SANE_Int direction,
408 				   SANE_Int curve1, SANE_Int curve2);
409 static void Motor_Curve_Free (struct st_motorcurve **motorcurves,
410 			      SANE_Int * mtc_count);
411 static struct st_curve *Motor_Curve_Get (struct st_device *dev,
412 					 SANE_Int motorcurve,
413 					 SANE_Int direction, SANE_Int itype);
414 static struct st_motorcurve **Motor_Curve_Parse (SANE_Int * mtc_count,
415 						 SANE_Int * buffer);
416 
417 /* Functions to arrange scanned lines */
418 static SANE_Int Arrange_Colour (struct st_device *dev, SANE_Byte * buffer,
419 				SANE_Int buffer_size, SANE_Int * transferred);
420 static SANE_Int Arrange_Compose (struct st_device *dev, SANE_Byte * buffer,
421 				 SANE_Int buffer_size,
422 				 SANE_Int * transferred);
423 static SANE_Int Arrange_NonColour (struct st_device *dev, SANE_Byte * buffer,
424 				   SANE_Int buffer_size,
425 				   SANE_Int * transferred);
426 
427 /* Composing RGB triplet functions */
428 static void Triplet_Gray (SANE_Byte * pPointer1, SANE_Byte * pPointer2,
429 			  SANE_Byte * buffer, SANE_Int channels_count);
430 static void Triplet_Lineart (SANE_Byte * pPointer1, SANE_Byte * pPointer2,
431 			     SANE_Byte * buffer, SANE_Int channels_count);
432 static void Triplet_Compose_Order (struct st_device *dev, SANE_Byte * pRed,
433 				   SANE_Byte * pGreen, SANE_Byte * pBlue,
434 				   SANE_Byte * buffer, SANE_Int dots);
435 static void Triplet_Compose_HRes (SANE_Byte * pPointer1,
436 				  SANE_Byte * pPointer2,
437 				  SANE_Byte * pPointer3,
438 				  SANE_Byte * pPointer4,
439 				  SANE_Byte * pPointer5,
440 				  SANE_Byte * pPointer6, SANE_Byte * buffer,
441 				  SANE_Int Width);
442 static void Triplet_Compose_LRes (SANE_Byte * pRed, SANE_Byte * pGreen,
443 				  SANE_Byte * pBlue, SANE_Byte * buffer,
444 				  SANE_Int dots);
445 static void Triplet_Colour_Order (struct st_device *dev, SANE_Byte * pRed,
446 				  SANE_Byte * pGreen, SANE_Byte * pBlue,
447 				  SANE_Byte * buffer, SANE_Int Width);
448 static void Triplet_Colour_HRes (SANE_Byte * pRed1, SANE_Byte * pGreen1,
449 				 SANE_Byte * pBlue1, SANE_Byte * pRed2,
450 				 SANE_Byte * pGreen2, SANE_Byte * pBlue2,
451 				 SANE_Byte * buffer, SANE_Int Width);
452 static void Triplet_Colour_LRes (SANE_Int Width, SANE_Byte * Buffer,
453 				 SANE_Byte * pChannel1, SANE_Byte * pChannel2,
454 				 SANE_Byte * pChannel3);
455 
456 /* Timing functions */
457 static SANE_Int Timing_SetLinearImageSensorClock (SANE_Byte * Regs,
458 						  struct st_cph *cph);
459 
460 /* Functions used to resize retrieved image */
461 static SANE_Int Resize_Start (struct st_device *dev, SANE_Int * transferred);
462 static SANE_Int Resize_CreateBuffers (struct st_device *dev, SANE_Int size1,
463 				      SANE_Int size2, SANE_Int size3);
464 static SANE_Int Resize_DestroyBuffers (struct st_device *dev);
465 static SANE_Int Resize_Increase (SANE_Byte * to_buffer,
466 				 SANE_Int to_resolution, SANE_Int to_width,
467 				 SANE_Byte * from_buffer,
468 				 SANE_Int from_resolution,
469 				 SANE_Int from_width, SANE_Int myresize_mode);
470 static SANE_Int Resize_Decrease (SANE_Byte * to_buffer,
471 				 SANE_Int to_resolution, SANE_Int to_width,
472 				 SANE_Byte * from_buffer,
473 				 SANE_Int from_resolution,
474 				 SANE_Int from_width, SANE_Int myresize_mode);
475 
476 /* Scanner buttons support */
477 static SANE_Int Buttons_Count (struct st_device *dev);
478 static SANE_Int Buttons_Enable (struct st_device *dev);
479 static SANE_Int Buttons_Order (struct st_device *dev, SANE_Int mask);
480 static SANE_Int Buttons_Status (struct st_device *dev);
481 static SANE_Int Buttons_Released (struct st_device *dev);
482 
483 /* Calibration functions */
484 static SANE_Int Calib_CreateBuffers (struct st_device *dev,
485 				     struct st_calibration *buffer,
486 				     SANE_Int my14b4);
487 static SANE_Int Calib_CreateFixedBuffers (void);
488 static void Calib_FreeBuffers (struct st_calibration *caltables);
489 static void Calib_LoadCut (struct st_device *dev,
490 			   struct st_scanparams *scancfg, SANE_Int scantype,
491 			   struct st_calibration_config *calibcfg);
492 static SANE_Int Calib_AdcGain (struct st_device *dev,
493 			       struct st_calibration_config *calibcfg,
494 			       SANE_Int arg2, SANE_Int gainmode);
495 static SANE_Int Calib_AdcOffsetRT (struct st_device *dev,
496 				   struct st_calibration_config *calibcfg,
497 				   SANE_Int value);
498 static SANE_Int Calib_BlackShading (struct st_device *dev,
499 				    struct st_calibration_config *calibcfg,
500 				    struct st_calibration *myCalib,
501 				    SANE_Int gainmode);
502 static SANE_Int Calib_BWShading (struct st_calibration_config *calibcfg,
503 				 struct st_calibration *myCalib,
504 				 SANE_Int gainmode);
505 static SANE_Int Calib_WhiteShading_3 (struct st_device *dev,
506 				      struct st_calibration_config *calibcfg,
507 				      struct st_calibration *myCalib,
508 				      SANE_Int gainmode);
509 static void Calibrate_Free (struct st_cal2 *calbuffers);
510 static SANE_Int Calibrate_Malloc (struct st_cal2 *calbuffers,
511 				  SANE_Byte * Regs,
512 				  struct st_calibration *myCalib,
513 				  SANE_Int somelength);
514 static SANE_Int Calib_ReadTable (struct st_device *dev, SANE_Byte * table,
515 				 SANE_Int size, SANE_Int data);
516 static SANE_Int Calib_WriteTable (struct st_device *dev, SANE_Byte * table,
517 				  SANE_Int size, SANE_Int data);
518 static SANE_Int Calib_LoadConfig (struct st_device *dev,
519 				  struct st_calibration_config *calibcfg,
520 				  SANE_Int scantype, SANE_Int resolution,
521 				  SANE_Int bitmode);
522 static SANE_Int Calib_PAGain (struct st_device *dev,
523 			      struct st_calibration_config *calibcfg,
524 			      SANE_Int gainmode);
525 static SANE_Int Calibration (struct st_device *dev, SANE_Byte * Regs,
526 			     struct st_scanparams *scancfg,
527 			     struct st_calibration *myCalib, SANE_Int value);
528 
529 /* function for white shading correction */
530 static SANE_Int WShading_Calibrate (struct st_device *dev, SANE_Byte * Regs,
531 				    struct st_calibration *myCalib,
532 				    struct st_scanparams *scancfg);
533 static void WShading_Emulate (SANE_Byte * buffer, SANE_Int * chnptr,
534 			      SANE_Int size, SANE_Int depth);
535 
536 /* functions for shading calibration */
537 static SANE_Int Shading_apply (struct st_device *dev, SANE_Byte * Regs,
538 			       struct st_scanparams *myvar,
539 			       struct st_calibration *myCalib);
540 static SANE_Int Shading_black_apply (struct st_device *dev, SANE_Byte * Regs,
541 				     SANE_Int channels,
542 				     struct st_calibration *myCalib,
543 				     struct st_cal2 *calbuffers);
544 static SANE_Int Shading_white_apply (struct st_device *dev, SANE_Byte * Regs,
545 				     SANE_Int channels,
546 				     struct st_calibration *myCalib,
547 				     struct st_cal2 *calbuffers);
548 
549 /* Spread-Spectrum Clock Generator functions */
550 static SANE_Int SSCG_Enable (struct st_device *dev);
551 
552 static void Split_into_12bit_channels (SANE_Byte * destino,
553 				       SANE_Byte * fuente, SANE_Int size);
554 static SANE_Int Scan_Read_BufferA (struct st_device *dev,
555 				   SANE_Int buffer_size, SANE_Int arg2,
556 				   SANE_Byte * pBuffer,
557 				   SANE_Int * bytes_transferred);
558 
559 static SANE_Int Bulk_Operation (struct st_device *dev, SANE_Byte op,
560 				SANE_Int buffer_size, SANE_Byte * buffer,
561 				SANE_Int * transferred);
562 static SANE_Int Get_PAG_Value (SANE_Byte scantype, SANE_Byte color);
563 static SANE_Int GetOneLineInfo (struct st_device *dev, SANE_Int resolution,
564 				SANE_Int * maximus, SANE_Int * minimus,
565 				double *average);
566 
567 static SANE_Int Load_StripCoords (SANE_Int scantype, SANE_Int * ypos,
568 				  SANE_Int * xpos);
569 
570 /*static SANE_Int Free_Fixed_CalBuffer(void);*/
571 static SANE_Int SetMultiExposure (struct st_device *dev, SANE_Byte * Regs);
572 
573 static void Set_E950_Mode (struct st_device *dev, SANE_Byte mode);
574 
575 static SANE_Int LoadImagingParams (struct st_device *dev, SANE_Int inifile);
576 
577 static SANE_Int SetScanParams (struct st_device *dev, SANE_Byte * Regs,
578 			       struct st_scanparams *scancfg,
579 			       struct st_hwdconfig *hwdcfg);
580 static SANE_Int IsScannerLinked (struct st_device *dev);
581 
582 static SANE_Int Read_FE3E (struct st_device *dev, SANE_Byte * destino);
583 
584 static double get_shrd (double value, SANE_Int desp);
585 static char get_byte (double value);
586 /*static SANE_Int RTS8822_GetRegisters(SANE_Byte *buffer);*/
587 
588 /* ----------------- Implementation ------------------*/
589 
590 static void
RTS_Free(struct st_device * dev)591 RTS_Free (struct st_device *dev)
592 {
593   /* this function frees space of devices's variable */
594 
595   if (dev != NULL)
596     {
597       /* next function shouldn't be necessary but I can NOT assure that other
598          programmers will call Free_Config before this function */
599       Free_Config (dev);
600 
601       if (dev->init_regs != NULL)
602 	free (dev->init_regs);
603 
604       if (dev->Resize != NULL)
605 	free (dev->Resize);
606 
607       if (dev->Reading != NULL)
608 	free (dev->Reading);
609 
610       if (dev->scanning != NULL)
611 	free (dev->scanning);
612 
613       if (dev->status != NULL)
614 	free (dev->status);
615 
616       free (dev);
617     }
618 }
619 
620 static struct st_device *
RTS_Alloc()621 RTS_Alloc ()
622 {
623   /* this function allocates space for device's variable */
624 
625   struct st_device *dev = NULL;
626 
627   dev = malloc (sizeof (struct st_device));
628   if (dev != NULL)
629     {
630       SANE_Int rst = OK;
631 
632       memset (dev, 0, sizeof (struct st_device));
633 
634       /* initial registers */
635       dev->init_regs = malloc (sizeof (SANE_Byte) * RT_BUFFER_LEN);
636       if (dev->init_regs != NULL)
637 	memset (dev->init_regs, 0, sizeof (SANE_Byte) * RT_BUFFER_LEN);
638       else
639 	rst = ERROR;
640 
641       if (rst == OK)
642 	{
643 	  dev->scanning = malloc (sizeof (struct st_scanning));
644 	  if (dev->scanning != NULL)
645 	    memset (dev->scanning, 0, sizeof (struct st_scanning));
646 	  else
647 	    rst = ERROR;
648 	}
649 
650       if (rst == OK)
651 	{
652 	  dev->Reading = malloc (sizeof (struct st_readimage));
653 	  if (dev->Reading != NULL)
654 	    memset (dev->Reading, 0, sizeof (struct st_readimage));
655 	  else
656 	    rst = ERROR;
657 	}
658 
659       if (rst == OK)
660 	{
661 	  dev->Resize = malloc (sizeof (struct st_resize));
662 	  if (dev->Resize != NULL)
663 	    memset (dev->Resize, 0, sizeof (struct st_resize));
664 	  else
665 	    rst = ERROR;
666 	}
667 
668       if (rst == OK)
669 	{
670 	  dev->status = malloc (sizeof (struct st_status));
671 	  if (dev->status != NULL)
672 	    memset (dev->status, 0, sizeof (struct st_status));
673 	  else
674 	    rst = ERROR;
675 	}
676 
677       /* if something fails, free space */
678       if (rst != OK)
679 	{
680 	  RTS_Free (dev);
681 	  dev = NULL;
682 	}
683     }
684 
685   return dev;
686 }
687 
688 static void
RTS_Scanner_End(struct st_device * dev)689 RTS_Scanner_End (struct st_device *dev)
690 {
691   Gamma_FreeTables ();
692   Free_Config (dev);
693   Free_Vars ();
694 }
695 
696 static SANE_Int
Device_get(SANE_Int product,SANE_Int vendor)697 Device_get (SANE_Int product, SANE_Int vendor)
698 {
699   return cfg_device_get (product, vendor);
700 }
701 
702 static SANE_Int
RTS_Scanner_Init(struct st_device * dev)703 RTS_Scanner_Init (struct st_device *dev)
704 {
705   SANE_Int rst;
706 
707   DBG (DBG_FNC, "> RTS_Scanner_Init:\n");
708   DBG (DBG_FNC, "> Backend version: %s\n", BACKEND_VRSN);
709 
710   rst = ERROR;
711 
712   /* gets usb type of this scanner if it's not already set by user */
713   if (RTS_Debug->usbtype == -1)
714     RTS_Debug->usbtype = RTS_USBType (dev);
715 
716   if (RTS_Debug->usbtype != ERROR)
717     {
718       DBG (DBG_FNC, " -> Chipset model ID: %i\n", Chipset_ID (dev));
719 
720       Chipset_Reset (dev);
721 
722       if (Load_Config (dev) == OK)
723 	{
724 	  if (IsScannerLinked (dev) == OK)
725 	    {
726 	      Set_E950_Mode (dev, 0);
727 	      Gamma_AllocTable (NULL);
728 	      rst = OK;
729 	    }
730 	  else
731 	    Free_Config (dev);
732 	}
733     }
734 
735   return rst;
736 }
737 
738 static SANE_Int
RTS_WriteRegs(USB_Handle usb_handle,SANE_Byte * buffer)739 RTS_WriteRegs (USB_Handle usb_handle, SANE_Byte * buffer)
740 {
741   SANE_Int rst = ERROR;
742 
743   if (buffer != NULL)
744     rst =
745       Write_Buffer (usb_handle, 0xe800, buffer,
746 		    RT_BUFFER_LEN * sizeof (SANE_Byte));
747 
748   return rst;
749 }
750 
751 static SANE_Int
RTS_ReadRegs(USB_Handle usb_handle,SANE_Byte * buffer)752 RTS_ReadRegs (USB_Handle usb_handle, SANE_Byte * buffer)
753 {
754   SANE_Int rst = ERROR;
755 
756   if (buffer != NULL)
757     rst =
758       Read_Buffer (usb_handle, 0xe800, buffer,
759 		   RT_BUFFER_LEN * sizeof (SANE_Byte));
760 
761   return rst;
762 }
763 
764 static void
SetLock(USB_Handle usb_handle,SANE_Byte * Regs,SANE_Byte Enable)765 SetLock (USB_Handle usb_handle, SANE_Byte * Regs, SANE_Byte Enable)
766 {
767   SANE_Byte lock;
768 
769   DBG (DBG_FNC, "+ SetLock(*Regs, Enable=%i):\n", Enable);
770 
771   if (Regs == NULL)
772     {
773       if (Read_Byte (usb_handle, 0xee00, &lock) != OK)
774 	lock = 0;
775     }
776   else
777     lock = Regs[0x600];
778 
779   if (Enable == FALSE)
780     lock &= 0xfb;
781   else
782     lock |= 4;
783 
784   if (Regs != NULL)
785     Regs[0x600] = lock;
786 
787   Write_Byte (usb_handle, 0xee00, lock);
788 
789   DBG (DBG_FNC, "- SetLock\n");
790 }
791 
792 static void
Set_E950_Mode(struct st_device * dev,SANE_Byte mode)793 Set_E950_Mode (struct st_device *dev, SANE_Byte mode)
794 {
795   SANE_Int data;
796 
797   DBG (DBG_FNC, "+ Set_E950_Mode(mode=%i):\n", mode);
798 
799   if (Read_Word (dev->usb_handle, 0xe950, &data) == OK)
800     {
801       data = (mode == 0) ? data & 0xffbf : data | 0x40;
802       Write_Word (dev->usb_handle, 0xe950, data);
803     }
804 
805   DBG (DBG_FNC, "- Set_E950_Mode\n");
806 }
807 
808 static struct st_curve *
Motor_Curve_Get(struct st_device * dev,SANE_Int motorcurve,SANE_Int direction,SANE_Int itype)809 Motor_Curve_Get (struct st_device *dev, SANE_Int motorcurve,
810 		 SANE_Int direction, SANE_Int itype)
811 {
812   struct st_curve *rst = NULL;
813 
814   if (dev != NULL)
815     {
816       if ((dev->mtrsetting != NULL) && (motorcurve < dev->mtrsetting_count))
817 	{
818 	  struct st_motorcurve *mtc = dev->mtrsetting[motorcurve];
819 
820 	  if (mtc != NULL)
821 	    {
822 	      if ((mtc->curve != NULL) && (mtc->curve_count > 0))
823 		{
824 		  struct st_curve *crv;
825 		  SANE_Int a = 0;
826 
827 		  while (a < mtc->curve_count)
828 		    {
829 		      /* get each curve */
830 		      crv = mtc->curve[a];
831 		      if (crv != NULL)
832 			{
833 			  /* check direction and type */
834 			  if ((crv->crv_speed == direction)
835 			      && (crv->crv_type == itype))
836 			    {
837 			      /* found ! */
838 			      rst = crv;
839 			      break;
840 			    }
841 			}
842 		      a++;
843 		    }
844 		}
845 	    }
846 	}
847     }
848 
849   return rst;
850 }
851 
852 static SANE_Int
Motor_Curve_Equal(struct st_device * dev,SANE_Int motorsetting,SANE_Int direction,SANE_Int curve1,SANE_Int curve2)853 Motor_Curve_Equal (struct st_device *dev, SANE_Int motorsetting,
854 		   SANE_Int direction, SANE_Int curve1, SANE_Int curve2)
855 {
856   /* compares two curves of the same direction
857      returns TRUE if both buffers are equal */
858 
859   SANE_Int rst = FALSE;
860   struct st_curve *crv1 =
861     Motor_Curve_Get (dev, motorsetting, direction, curve1);
862   struct st_curve *crv2 =
863     Motor_Curve_Get (dev, motorsetting, direction, curve2);
864 
865   if ((crv1 != NULL) && (crv2 != NULL))
866     {
867       if (crv1->step_count == crv2->step_count)
868 	{
869 	  rst = TRUE;
870 
871 	  if (crv1->step_count > 0)
872 	    {
873 	      SANE_Int a = 0;
874 
875 	      while ((a < crv1->step_count) && (rst == TRUE))
876 		{
877 		  rst = (crv1->step[a] == crv2->step[a]) ? TRUE : FALSE;
878 		  a++;
879 		}
880 	    }
881 	}
882     }
883 
884   return rst;
885 }
886 
887 static struct st_motorcurve **
Motor_Curve_Parse(SANE_Int * mtc_count,SANE_Int * buffer)888 Motor_Curve_Parse (SANE_Int * mtc_count, SANE_Int * buffer)
889 {
890   /* this function parses motorcurve buffer to get all motor settings */
891   struct st_motorcurve **rst = NULL;
892 
893   *mtc_count = 0;
894 
895   if (buffer != NULL)
896     {
897       /* phases:
898          -1 : null phase
899          0 :
900          -3 : initial config
901        */
902       struct st_motorcurve *mtc = NULL;
903       SANE_Int phase;
904 
905       phase = -1;
906       while (*buffer != -1)
907 	{
908 	  if (*buffer == -2)
909 	    {
910 	      /* end of motorcurve */
911 	      /* complete any opened phase */
912 	      /* close phase */
913 	      phase = -1;
914 	    }
915 	  else
916 	    {
917 	      /* step */
918 	      if (phase == -1)
919 		{
920 		  /* new motorcurve */
921 		  phase = 0;
922 		  mtc =
923 		    (struct st_motorcurve *)
924 		    malloc (sizeof (struct st_motorcurve));
925 		  if (mtc != NULL)
926 		    {
927 		      *mtc_count += 1;
928 		      rst =
929 			realloc (rst,
930 				 sizeof (struct st_motorcurve **) *
931 				 *mtc_count);
932 		      if (rst != NULL)
933 			{
934 			  rst[*mtc_count - 1] = mtc;
935 			  memset (mtc, 0, sizeof (struct st_motorcurve));
936 			  phase = -3;	/* initial config */
937 			}
938 		      else
939 			{
940 			  /* memory error */
941 			  *mtc_count = 0;
942 			  break;
943 			}
944 		    }
945 		  else
946 		    break;	/* some error */
947 		}
948 
949 	      if (mtc != NULL)
950 		{
951 		  switch (phase)
952 		    {
953 		    case -3:	/* initial config */
954 		      mtc->mri = *(buffer);
955 		      mtc->msi = *(buffer + 1);
956 		      mtc->skiplinecount = *(buffer + 2);
957 		      mtc->motorbackstep = *(buffer + 3);
958 		      buffer += 3;
959 
960 		      phase = -4;
961 		      break;
962 
963 		    case -4:
964 		      /**/
965 		      {
966 			/* create new step curve */
967 			struct st_curve *curve =
968 			  malloc (sizeof (struct st_curve));
969 			if (curve != NULL)
970 			  {
971 			    /* add to step curve list */
972 			    mtc->curve =
973 			      (struct st_curve **) realloc (mtc->curve,
974 							    sizeof (struct
975 								    st_curve
976 								    **) *
977 							    (mtc->
978 							     curve_count +
979 							     1));
980 			    if (mtc->curve != NULL)
981 			      {
982 				mtc->curve_count++;
983 				mtc->curve[mtc->curve_count - 1] = curve;
984 
985 				memset (curve, 0, sizeof (struct st_curve));
986 				/* read crv speed and type */
987 				curve->crv_speed = *buffer;
988 				curve->crv_type = *(buffer + 1);
989 				buffer += 2;
990 
991 				/* get length of step buffer */
992 				while (*(buffer + curve->step_count) != 0)
993 				  curve->step_count++;
994 
995 				if (curve->step_count > 0)
996 				  {
997 				    /* allocate step buffer */
998 				    curve->step =
999 				      (SANE_Int *) malloc (sizeof (SANE_Int) *
1000 							   curve->step_count);
1001 				    if (curve->step != NULL)
1002 				      {
1003 					memcpy (curve->step, buffer,
1004 						sizeof (SANE_Int) *
1005 						curve->step_count);
1006 					buffer += curve->step_count;
1007 				      }
1008 				    else
1009 				      curve->step_count = 0;
1010 				  }
1011 			      }
1012 			    else
1013 			      {
1014 				mtc->curve_count = 0;
1015 				free (curve);
1016 			      }
1017 			  }
1018 			else
1019 			  break;
1020 		      }
1021 		      break;
1022 		    }
1023 		}
1024 	    }
1025 	  buffer++;
1026 	}
1027     }
1028 
1029   return rst;
1030 }
1031 
1032 static void
Motor_Curve_Free(struct st_motorcurve ** motorcurves,SANE_Int * mtc_count)1033 Motor_Curve_Free (struct st_motorcurve **motorcurves, SANE_Int * mtc_count)
1034 {
1035   if ((motorcurves != NULL) && (mtc_count != NULL))
1036     {
1037       struct st_motorcurve *mtc;
1038       struct st_curve *curve;
1039 
1040       while (*mtc_count > 0)
1041 	{
1042 	  mtc = motorcurves[*mtc_count - 1];
1043 	  if (mtc != NULL)
1044 	    {
1045 	      if (mtc->curve != NULL)
1046 		{
1047 		  while (mtc->curve_count > 0)
1048 		    {
1049 		      curve = mtc->curve[mtc->curve_count - 1];
1050 		      if (curve != NULL)
1051 			{
1052 			  if (curve->step != NULL)
1053 			    free (curve->step);
1054 
1055 			  free (curve);
1056 			}
1057 		      mtc->curve_count--;
1058 		    }
1059 		}
1060 	      free (mtc);
1061 	    }
1062 	  *mtc_count -= 1;
1063 	}
1064 
1065       free (motorcurves);
1066     }
1067 }
1068 
1069 static SANE_Byte
RTS_Sensor_Type(USB_Handle usb_handle)1070 RTS_Sensor_Type (USB_Handle usb_handle)
1071 {
1072   /*
1073      Returns sensor type
1074      01 = CCD
1075      00 = CIS
1076    */
1077 
1078   SANE_Int a, b, c;
1079   SANE_Byte rst;
1080 
1081   DBG (DBG_FNC, "+ RTS_Sensor_Type:\n");
1082 
1083   a = b = c = 0;
1084 
1085   /* Save data first */
1086   Read_Word (usb_handle, 0xe950, &a);
1087   Read_Word (usb_handle, 0xe956, &b);
1088 
1089   /* Enables GPIO 0xe950 writing directly 0x13ff */
1090   Write_Word (usb_handle, 0xe950, 0x13ff);
1091   /* Sets GPIO 0xe956 writing 0xfcf0 */
1092   Write_Word (usb_handle, 0xe956, 0xfcf0);
1093   /* Makes a sleep of 200 ms */
1094   usleep (1000 * 200);
1095   /* Get GPIO 0xe968 */
1096   Read_Word (usb_handle, 0xe968, &c);
1097   /* Restore data */
1098   Write_Word (usb_handle, 0xe950, a);
1099   Write_Word (usb_handle, 0xe956, b);
1100 
1101   rst = ((_B1 (c) & 1) == 0) ? CCD_SENSOR : CIS_SENSOR;
1102 
1103   DBG (DBG_FNC, "- RTS_Sensor_Type: %s\n",
1104        (rst == CCD_SENSOR) ? "CCD" : "CIS");
1105 
1106   return rst;
1107 }
1108 
1109 static void
Free_Scanmodes(struct st_device * dev)1110 Free_Scanmodes (struct st_device *dev)
1111 {
1112   DBG (DBG_FNC, "> Free_Scanmodes\n");
1113 
1114   if (dev->scanmodes != NULL)
1115     {
1116       if (dev->scanmodes_count > 0)
1117 	{
1118 	  SANE_Int a;
1119 	  for (a = 0; a < dev->scanmodes_count; a++)
1120 	    if (dev->scanmodes[a] != NULL)
1121 	      free (dev->scanmodes[a]);
1122 	}
1123 
1124       free (dev->scanmodes);
1125       dev->scanmodes = NULL;
1126     }
1127 
1128   dev->scanmodes_count = 0;
1129 }
1130 
1131 static SANE_Int
Load_Scanmodes(struct st_device * dev)1132 Load_Scanmodes (struct st_device *dev)
1133 {
1134   SANE_Int rst = OK;
1135   SANE_Int a, b;
1136   struct st_scanmode reg, *mode;
1137 
1138   DBG (DBG_FNC, "> Load_Scanmodes\n");
1139 
1140   if ((dev->scanmodes != NULL) || (dev->scanmodes_count > 0))
1141     Free_Scanmodes (dev);
1142 
1143   a = 0;
1144   while ((cfg_scanmode_get (dev->sensorcfg->type, a, &reg) == OK)
1145 	 && (rst == OK))
1146     {
1147       mode = (struct st_scanmode *) malloc (sizeof (struct st_scanmode));
1148       if (mode != NULL)
1149 	{
1150 	  memcpy (mode, &reg, sizeof (struct st_scanmode));
1151 
1152 	  for (b = 0; b < 3; b++)
1153 	    {
1154 	      if (mode->mexpt[b] == 0)
1155 		{
1156 		  mode->mexpt[b] = mode->ctpc;
1157 		  if (mode->multiexposure != 1)
1158 		    mode->expt[b] = mode->ctpc;
1159 		}
1160 	    }
1161 
1162 	  mode->ctpc = ((mode->ctpc + 1) * mode->multiexposure) - 1;
1163 
1164 	  dev->scanmodes =
1165 	    (struct st_scanmode **) realloc (dev->scanmodes,
1166 					     (dev->scanmodes_count +
1167 					      1) *
1168 					     sizeof (struct st_scanmode **));
1169 	  if (dev->scanmodes != NULL)
1170 	    {
1171 	      dev->scanmodes[dev->scanmodes_count] = mode;
1172 	      dev->scanmodes_count++;
1173 	    }
1174 	  else
1175 	    rst = ERROR;
1176 	}
1177       else
1178 	rst = ERROR;
1179 
1180       a++;
1181     }
1182 
1183   if (rst == ERROR)
1184     Free_Scanmodes (dev);
1185 
1186   DBG (DBG_FNC, " -> Found %i scanmodes\n", dev->scanmodes_count);
1187   dbg_scanmodes (dev);
1188 
1189   return rst;
1190 }
1191 
1192 static void
Free_Config(struct st_device * dev)1193 Free_Config (struct st_device *dev)
1194 {
1195   DBG (DBG_FNC, "+ Free_Config\n");
1196 
1197   /* free buttons */
1198   Free_Buttons (dev);
1199 
1200   /* free motor general configuration */
1201   Free_Motor (dev);
1202 
1203   /* free sensor main configuration */
1204   Free_Sensor (dev);
1205 
1206   /* free ccd sensor timing tables */
1207   Free_Timings (dev);
1208 
1209   /* free motor curves */
1210   Free_MotorCurves (dev);
1211 
1212   /* free motor movements */
1213   Free_Motormoves (dev);
1214 
1215   /* free scan modes */
1216   Free_Scanmodes (dev);
1217 
1218   /* free constrains */
1219   Free_Constrains (dev);
1220 
1221   /* free chipset configuration */
1222   Free_Chipset (dev);
1223 
1224   DBG (DBG_FNC, "- Free_Config\n");
1225 }
1226 
1227 static void
Free_Chipset(struct st_device * dev)1228 Free_Chipset (struct st_device *dev)
1229 {
1230   DBG (DBG_FNC, "> Free_Chipset\n");
1231 
1232   if (dev->chipset != NULL)
1233     {
1234       if (dev->chipset->name != NULL)
1235 	free (dev->chipset->name);
1236 
1237       free (dev->chipset);
1238       dev->chipset = NULL;
1239     }
1240 }
1241 
1242 static SANE_Int
Load_Chipset(struct st_device * dev)1243 Load_Chipset (struct st_device *dev)
1244 {
1245   SANE_Int rst = ERROR;
1246 
1247   DBG (DBG_FNC, "> Load_Chipset\n");
1248 
1249   if (dev->chipset != NULL)
1250     Free_Chipset (dev);
1251 
1252   dev->chipset = malloc (sizeof (struct st_chip));
1253   if (dev->chipset != NULL)
1254     {
1255       SANE_Int model;
1256 
1257       memset (dev->chipset, 0, sizeof (struct st_chip));
1258 
1259       /* get chipset model of selected scanner */
1260       model = cfg_chipset_model_get (RTS_Debug->dev_model);
1261 
1262       /* get configuration for selected chipset */
1263       rst = cfg_chipset_get (model, dev->chipset);
1264     }
1265 
1266   /* if rst == ERROR may be related to allocating space for chipset name */
1267 
1268   return rst;
1269 }
1270 
1271 static SANE_Int
Load_Config(struct st_device * dev)1272 Load_Config (struct st_device *dev)
1273 {
1274   DBG (DBG_FNC, "+ Load_Config\n");
1275 
1276   /* load chipset configuration */
1277   Load_Chipset (dev);
1278 
1279   /* load scanner's buttons */
1280   Load_Buttons (dev);
1281 
1282   /* load scanner area constrains */
1283   Load_Constrains (dev);
1284 
1285   /* load motor general configuration */
1286   Load_Motor (dev);
1287 
1288   /* load sensor main configuration */
1289   Load_Sensor (dev);
1290 
1291   if (dev->sensorcfg->type == -1)
1292     /* get sensor from gpio */
1293     dev->sensorcfg->type = RTS_Sensor_Type (dev->usb_handle);
1294 
1295   /* load ccd sensor timing tables */
1296   Load_Timings (dev);
1297 
1298   /* load motor curves */
1299   Load_MotorCurves (dev);
1300 
1301   /* load motor movements */
1302   Load_Motormoves (dev);
1303 
1304   /* load scan modes */
1305   Load_Scanmodes (dev);
1306 
1307   /* deprecated */
1308   if (dev->sensorcfg->type == CCD_SENSOR)
1309     /* ccd */ usbfile =
1310       (RTS_Debug->usbtype == USB20) ? T_RTINIFILE : T_USB1INIFILE;
1311   else				/* cis */
1312     usbfile = (RTS_Debug->usbtype == USB20) ? S_RTINIFILE : S_USB1INIFILE;
1313 
1314   scantype = ST_NORMAL;
1315 
1316   pwmlamplevel = get_value (SCAN_PARAM, PWMLAMPLEVEL, 1, usbfile);
1317 
1318   arrangeline2 = get_value (SCAN_PARAM, ARRANGELINE, FIX_BY_HARD, usbfile);
1319 
1320   shadingbase = get_value (TRUE_GRAY_PARAM, SHADINGBASE, 3, usbfile);
1321   shadingfact[0] = get_value (TRUE_GRAY_PARAM, SHADINGFACT1, 1, usbfile);
1322   shadingfact[1] = get_value (TRUE_GRAY_PARAM, SHADINGFACT2, 1, usbfile);
1323   shadingfact[2] = get_value (TRUE_GRAY_PARAM, SHADINGFACT3, 1, usbfile);
1324 
1325   LoadImagingParams (dev, usbfile);
1326 
1327   DBG (DBG_FNC, "- Load_Config\n");
1328 
1329   return OK;
1330 }
1331 
1332 static SANE_Int
LoadImagingParams(struct st_device * dev,SANE_Int inifile)1333 LoadImagingParams (struct st_device *dev, SANE_Int inifile)
1334 {
1335   DBG (DBG_FNC, "> LoadImagingParams(inifile='%i'):\n", inifile);
1336 
1337   scan.startpos = get_value (SCAN_PARAM, STARTPOS, 0, inifile);
1338   scan.leftleading = get_value (SCAN_PARAM, LEFTLEADING, 0, inifile);
1339   arrangeline = get_value (SCAN_PARAM, ARRANGELINE, FIX_BY_HARD, inifile);
1340   compression = get_value (SCAN_PARAM, COMPRESSION, 0, inifile);
1341 
1342   /* get default gain and offset values */
1343   cfg_gainoffset_get (dev->sensorcfg->type, default_gain_offset);
1344 
1345   linedarlampoff = get_value (CALI_PARAM, LINEDARLAMPOFF, 0, inifile);
1346 
1347   pixeldarklevel = get_value (CALI_PARAM, PIXELDARKLEVEL, 0x00ffff, inifile);
1348 
1349   binarythresholdh = get_value (PLATFORM, BINARYTHRESHOLDH, 0x80, inifile);
1350   binarythresholdl = get_value (PLATFORM, BINARYTHRESHOLDL, 0x7f, inifile);
1351 
1352   return OK;
1353 }
1354 
1355 static SANE_Int
Arrange_Colour(struct st_device * dev,SANE_Byte * buffer,SANE_Int buffer_size,SANE_Int * transferred)1356 Arrange_Colour (struct st_device *dev, SANE_Byte * buffer,
1357 		SANE_Int buffer_size, SANE_Int * transferred)
1358 {
1359   /*
1360      05F0FA78   04EC00D8  /CALL to Assumed StdFunc2 from hpgt3970.04EC00D3
1361      05F0FA7C   05D10048  |Arg1 = 05D10048
1362      05F0FA80   0000F906  \Arg2 = 0000F906
1363    */
1364   SANE_Int mydistance;
1365   SANE_Int Lines_Count;
1366   SANE_Int space;
1367   SANE_Int rst = OK;
1368   SANE_Int c;
1369   struct st_scanning *scn;
1370 
1371   DBG (DBG_FNC, "> Arrange_Colour(*buffer, buffer_size=%i, *transferred)\n",
1372        buffer_size);
1373 
1374   /* this is just to make code more legible */
1375   scn = dev->scanning;
1376 
1377   if (scn->imagebuffer == NULL)
1378     {
1379       if (dev->sensorcfg->type == CCD_SENSOR)
1380 	mydistance =
1381 	  (dev->sensorcfg->line_distance * scan2.resolution_y) /
1382 	  dev->sensorcfg->resolution;
1383       else
1384 	mydistance = 0;
1385 
1386       /*aafa */
1387       if (mydistance != 0)
1388 	{
1389 	  scn->bfsize =
1390 	    (scn->arrange_hres ==
1391 	     TRUE) ? scn->arrange_sensor_evenodd_dist : 0;
1392 	  scn->bfsize = (scn->bfsize + (mydistance * 2) + 1) * line_size;
1393 	}
1394       else
1395 	scn->bfsize = line_size * 2;
1396 
1397       /*ab3c */
1398       space =
1399 	(((scn->bfsize / line_size) * bytesperline) >
1400 	 scn->bfsize) ? (scn->bfsize / line_size) *
1401 	bytesperline : scn->bfsize;
1402 
1403       scn->imagebuffer = (SANE_Byte *) malloc (space * sizeof (SANE_Byte));
1404       if (scn->imagebuffer == NULL)
1405 	return ERROR;
1406 
1407       scn->imagepointer = scn->imagebuffer;
1408 
1409       if (Read_Block (dev, scn->bfsize, scn->imagebuffer, transferred) != OK)
1410 	return ERROR;
1411 
1412       scn->arrange_orderchannel = FALSE;
1413       scn->channel_size = (scan2.depth == 8) ? 1 : 2;
1414 
1415       /* Calculate channel displacements */
1416       for (c = CL_RED; c <= CL_BLUE; c++)
1417 	{
1418 	  if (mydistance == 0)
1419 	    {
1420 	      /*ab9b */
1421 	      if (scn->arrange_hres == FALSE)
1422 		{
1423 		  if ((((dev->sensorcfg->line_distance * scan2.resolution_y) *
1424 			2) / dev->sensorcfg->resolution) == 1)
1425 		    scn->arrange_orderchannel = TRUE;
1426 
1427 		  if (scn->arrange_orderchannel == TRUE)
1428 		    scn->desp[c] =
1429 		      ((dev->sensorcfg->rgb_order[c] / 2) * line_size) +
1430 		      (scn->channel_size * c);
1431 		  else
1432 		    scn->desp[c] = scn->channel_size * c;
1433 		}
1434 	    }
1435 	  else
1436 	    {
1437 	      /*ac32 */
1438 	      scn->desp[c] =
1439 		(dev->sensorcfg->rgb_order[c] * (mydistance * line_size)) +
1440 		(scn->channel_size * c);
1441 
1442 	      if (scn->arrange_hres == TRUE)
1443 		{
1444 		  scn->desp1[c] = scn->desp[c];
1445 		  scn->desp2[c] =
1446 		    ((scn->channel_size * 3) + scn->desp[c]) +
1447 		    (scn->arrange_sensor_evenodd_dist * line_size);
1448 		}
1449 	    }
1450 	}
1451 
1452       /*ace2 */
1453       for (c = CL_RED; c <= CL_BLUE; c++)
1454 	{
1455 	  if (scn->arrange_hres == TRUE)
1456 	    {
1457 	      scn->pColour2[c] = scn->imagebuffer + scn->desp2[c];
1458 	      scn->pColour1[c] = scn->imagebuffer + scn->desp1[c];
1459 	    }
1460 	  else
1461 	    scn->pColour[c] = scn->imagebuffer + scn->desp[c];
1462 	}
1463     }
1464 
1465   /*ad91 */
1466   Lines_Count = buffer_size / line_size;
1467   while (Lines_Count > 0)
1468     {
1469       if (scn->arrange_orderchannel == FALSE)
1470 	{
1471 	  if (scn->arrange_hres == TRUE)
1472 	    Triplet_Colour_HRes (scn->pColour1[CL_RED],
1473 				 scn->pColour1[CL_GREEN],
1474 				 scn->pColour1[CL_BLUE],
1475 				 scn->pColour2[CL_RED],
1476 				 scn->pColour2[CL_GREEN],
1477 				 scn->pColour2[CL_BLUE], buffer,
1478 				 line_size / (scn->channel_size * 3));
1479 	  else
1480 	    Triplet_Colour_LRes (line_size / (scn->channel_size * 3), buffer,
1481 				 scn->pColour[CL_RED], scn->pColour[CL_GREEN],
1482 				 scn->pColour[CL_BLUE]);
1483 	}
1484       else
1485 	Triplet_Colour_Order (dev, scn->pColour[CL_RED],
1486 			      scn->pColour[CL_GREEN], scn->pColour[CL_BLUE],
1487 			      buffer, line_size / (scn->channel_size * 3));
1488 
1489       scn->arrange_size -= bytesperline;
1490       if (scn->arrange_size < 0)
1491 	v15bc--;
1492 
1493       buffer += line_size;
1494 
1495       Lines_Count--;
1496       if (Lines_Count == 0)
1497 	{
1498 	  if ((scn->arrange_size | v15bc) == 0)
1499 	    return OK;
1500 	}
1501 
1502       if (Read_Block (dev, line_size, scn->imagepointer, transferred) ==
1503 	  ERROR)
1504 	return ERROR;
1505 
1506       /* Update displacements */
1507       for (c = CL_RED; c <= CL_BLUE; c++)
1508 	{
1509 	  if (scn->arrange_hres == TRUE)
1510 	    {
1511 	      /*aeb7 */
1512 	      scn->desp2[c] = (scn->desp2[c] + line_size) % scn->bfsize;
1513 	      scn->desp1[c] = (scn->desp1[c] + line_size) % scn->bfsize;
1514 
1515 	      scn->pColour2[c] = scn->imagebuffer + scn->desp2[c];
1516 	      scn->pColour1[c] = scn->imagebuffer + scn->desp1[c];
1517 	    }
1518 	  else
1519 	    {
1520 	      /*af86 */
1521 	      scn->desp[c] = (scn->desp[c] + line_size) % scn->bfsize;
1522 	      scn->pColour[c] = scn->imagebuffer + scn->desp[c];
1523 	    }
1524 	}
1525 
1526       /*aff3 */
1527       scn->imagepointer += line_size;
1528       if (scn->imagepointer >= (scn->imagebuffer + scn->bfsize))
1529 	scn->imagepointer = scn->imagebuffer;
1530     }
1531 
1532   return rst;
1533 }
1534 
1535 static SANE_Int
RTS_Scanner_SetParams(struct st_device * dev,struct params * param)1536 RTS_Scanner_SetParams (struct st_device *dev, struct params *param)
1537 {
1538   SANE_Int rst = ERROR;
1539 
1540   DBG (DBG_FNC, "+ RTS_Scanner_SetParams:\n");
1541   DBG (DBG_FNC, "->  param->resolution_x=%i\n", param->resolution_x);
1542   DBG (DBG_FNC, "->  param->resolution_y=%i\n", param->resolution_y);
1543   DBG (DBG_FNC, "->  param->left        =%i\n", param->coords.left);
1544   DBG (DBG_FNC, "->  param->width       =%i\n", param->coords.width);
1545   DBG (DBG_FNC, "->  param->top         =%i\n", param->coords.top);
1546   DBG (DBG_FNC, "->  param->height      =%i\n", param->coords.height);
1547   DBG (DBG_FNC, "->  param->colormode   =%s\n",
1548        dbg_colour (param->colormode));
1549   DBG (DBG_FNC, "->  param->scantype    =%s\n",
1550        dbg_scantype (param->scantype));
1551   DBG (DBG_FNC, "->  param->depth       =%i\n", param->depth);
1552   DBG (DBG_FNC, "->  param->channel     =%i\n", param->channel);
1553 
1554   /* validate area size to scan */
1555   if ((param->coords.width != 0) && (param->coords.height != 0))
1556     {
1557       SANE_Byte mybuffer[1];
1558       struct st_hwdconfig hwdcfg;
1559 
1560       /* setting coordinates */
1561       memcpy (&scan.coord, &param->coords, sizeof (struct st_coords));
1562 
1563       /* setting resolution */
1564       scan.resolution_x = param->resolution_x;
1565       scan.resolution_y = param->resolution_y;
1566 
1567       /* setting colormode and depth */
1568       scan.colormode = param->colormode;
1569       scan.depth = (param->colormode == CM_LINEART) ? 8 : param->depth;
1570 
1571       /* setting color channel for non color scans */
1572       scan.channel = _B0 (param->channel);
1573 
1574       arrangeline = FIX_BY_HARD;
1575       if ((scan.resolution_x == 2400) || ((scan.resolution_x == 4800)))
1576 	{
1577 	  if (scan.colormode != CM_COLOR)
1578 	    {
1579 	      if (scan.colormode == CM_GRAY)
1580 		{
1581 		  if (scan.channel == 3)
1582 		    arrangeline = FIX_BY_SOFT;
1583 		}
1584 	    }
1585 	  else
1586 	    arrangeline = FIX_BY_SOFT;
1587 	}
1588 
1589       /* setting scan type */
1590       if ((param->scantype > 0) && (param->scantype < 4))
1591 	scan.scantype = param->scantype;
1592       else
1593 	scan.scantype = ST_NORMAL;
1594 
1595       /* setting scanner lamp */
1596       data_bitset (&dev->init_regs[0x146], 0x40,
1597 		   ((dev->sensorcfg->type == CIS_SENSOR) ? 0 : 1));
1598 
1599       /* turn on appropriate lamp */
1600       if (scan.scantype == ST_NORMAL)
1601 	Lamp_Status_Set (dev, NULL, TRUE, FLB_LAMP);
1602       else
1603 	Lamp_Status_Set (dev, NULL, TRUE, TMA_LAMP);
1604 
1605       mybuffer[0] = 0;
1606       if (RTS_IsExecuting (dev, mybuffer) == FALSE)
1607 	RTS_WriteRegs (dev->usb_handle, dev->init_regs);
1608 
1609       if (scan.depth == 16)
1610 	compression = FALSE;
1611 
1612       /* resetting low level config */
1613       memset (&hwdcfg, 0, sizeof (struct st_hwdconfig));
1614 
1615       /* setting low level config */
1616       hwdcfg.scantype = scan.scantype;
1617       hwdcfg.calibrate = mybuffer[0];
1618       hwdcfg.arrangeline = arrangeline;	/*1 */
1619       hwdcfg.highresolution = (scan.resolution_x > 1200) ? TRUE : FALSE;
1620       hwdcfg.sensorevenodddistance = dev->sensorcfg->evenodd_distance;
1621 
1622       SetScanParams (dev, dev->init_regs, &scan, &hwdcfg);
1623 
1624       scan.shadinglength =
1625 	(((scan.sensorresolution * 17) / 2) + 3) & 0xfffffffc;
1626 
1627       rst = OK;
1628     }
1629 
1630   DBG (DBG_FNC, "- RTS_Scanner_SetParams: %i\n", rst);
1631 
1632   return rst;
1633 }
1634 
1635 static SANE_Int
SetScanParams(struct st_device * dev,SANE_Byte * Regs,struct st_scanparams * scancfg,struct st_hwdconfig * hwdcfg)1636 SetScanParams (struct st_device *dev, SANE_Byte * Regs,
1637 	       struct st_scanparams *scancfg, struct st_hwdconfig *hwdcfg)
1638 {
1639   struct st_coords mycoords;
1640   SANE_Int mycolormode;
1641   SANE_Int myvalue;
1642   SANE_Int mymode;
1643   SANE_Int channel_size;
1644   SANE_Int channel_count;
1645   SANE_Int dots_per_block;
1646   SANE_Int aditional_dots;
1647 
1648   DBG (DBG_FNC, "+ SetScanParams:\n");
1649   dbg_ScanParams (scancfg);
1650   dbg_hwdcfg (hwdcfg);
1651 
1652   memset (&mycoords, 0, sizeof (struct st_coords));
1653   /* Copy scancfg to scan2 */
1654   memcpy (&scan2, scancfg, sizeof (struct st_scanparams));
1655 
1656   mycolormode = scancfg->colormode;
1657   myvalue = scancfg->colormode;
1658   scantype = hwdcfg->scantype;
1659 
1660   if (scancfg->colormode == CM_LINEART)
1661     scan2.depth = 8;
1662 
1663   if ((scancfg->colormode != CM_COLOR) && (scancfg->channel == 3))	/*channel = 0x00 */
1664     {
1665       if (scancfg->colormode == CM_GRAY)
1666 	{
1667 	  mycolormode = (hwdcfg->arrangeline != FIX_BY_SOFT) ? 3 : CM_COLOR;
1668 	}
1669       else
1670 	mycolormode = 3;
1671       myvalue = mycolormode;
1672     }
1673 
1674   dev->Resize->resolution_x = scancfg->resolution_x;
1675   dev->Resize->resolution_y = scancfg->resolution_y;
1676 
1677   mymode = RTS_GetScanmode (dev, hwdcfg->scantype, myvalue, scancfg->resolution_x);	/*0x0b */
1678   if (mymode == -1)
1679     {
1680       /* Non supported resolution. We will resize image after scanning */
1681       SANE_Int fitres;
1682 
1683       fitres =
1684 	Scanmode_fitres (dev, hwdcfg->scantype, scancfg->colormode,
1685 			 scancfg->resolution_x);
1686       if (fitres != -1)
1687 	{
1688 	  /* supported resolution found */
1689 	  dev->Resize->type = RSZ_DECREASE;
1690 	}
1691       else
1692 	{
1693 	  dev->Resize->type = RSZ_INCREASE;
1694 	  fitres =
1695 	    Scanmode_maxres (dev, hwdcfg->scantype, scancfg->colormode);
1696 	}
1697 
1698       scan2.resolution_x = fitres;
1699       scan2.resolution_y = fitres;
1700 
1701       mymode =
1702 	RTS_GetScanmode (dev, hwdcfg->scantype, myvalue, scan2.resolution_x);
1703       if (mymode == -1)
1704 	return ERROR;
1705 
1706       imageheight = scancfg->coord.height;
1707       dev->Resize->towidth = scancfg->coord.width;
1708 
1709       /* Calculate coords for new resolution */
1710       mycoords.left =
1711 	(scan2.resolution_x * scancfg->coord.left) /
1712 	dev->Resize->resolution_x;
1713       mycoords.width =
1714 	(scan2.resolution_x * scancfg->coord.width) /
1715 	dev->Resize->resolution_x;
1716       mycoords.top =
1717 	(scan2.resolution_y * scancfg->coord.top) / dev->Resize->resolution_y;
1718       mycoords.height =
1719 	((scan2.resolution_y * scancfg->coord.height) /
1720 	 dev->Resize->resolution_y) + 2;
1721 
1722       switch (scan2.colormode)
1723 	{
1724 	case CM_GRAY:
1725 	  if ((dev->scanmodes[mymode]->samplerate == PIXEL_RATE)
1726 	      && (mycolormode != 3))
1727 	    dev->Resize->towidth *= 2;
1728 
1729 	  channel_size = (scan2.depth == 8) ? 1 : 2;
1730 	  dev->Resize->mode = (scan2.depth == 8) ? RSZ_GRAYL : RSZ_GRAYH;
1731 	  dev->Resize->bytesperline = dev->Resize->towidth * channel_size;
1732 	  break;
1733 	case CM_LINEART:
1734 	  if (dev->scanmodes[mymode]->samplerate == PIXEL_RATE)
1735 	    dev->Resize->towidth *= 2;
1736 
1737 	  dev->Resize->mode = RSZ_LINEART;
1738 	  dev->Resize->bytesperline = (dev->Resize->towidth + 7) / 8;
1739 	  break;
1740 	default:		/*CM_COLOR */
1741 	  channel_count = 3;
1742 	  channel_size = (scan2.depth == 8) ? 1 : 2;
1743 	  dev->Resize->mode = (scan2.depth == 8) ? RSZ_COLOURL : RSZ_COLOURH;
1744 	  dev->Resize->bytesperline =
1745 	    scancfg->coord.width * (channel_count * channel_size);
1746 	  break;
1747 	}
1748     }
1749   else
1750     {
1751       /* Supported scanmode */
1752       dev->Resize->type = RSZ_NONE;
1753       scan2.resolution_x = scancfg->resolution_x;
1754       scan2.resolution_y = scancfg->resolution_y;
1755       mycoords.left = scancfg->coord.left;
1756       mycoords.top = scancfg->coord.top;
1757       mycoords.width = scancfg->coord.width;
1758       mycoords.height = scancfg->coord.height;
1759     }
1760 
1761   scancfg->timing = dev->scanmodes[mymode]->timing;
1762 
1763   scan2.sensorresolution = dev->timings[scancfg->timing]->sensorresolution;
1764   if ((scantype > 0) && (scantype < 5))
1765     scan2.shadinglength =
1766       (((scan2.sensorresolution * 17) / 2) + 3) & 0xfffffffc;
1767 
1768   scancfg->sensorresolution = scan2.sensorresolution;
1769   scancfg->shadinglength = scan2.shadinglength;
1770 
1771   dev->scanning->arrange_compression = ((mycolormode != CM_LINEART)
1772 					&& (scan2.depth <=
1773 					    8)) ? hwdcfg->compression : FALSE;
1774 
1775   if ((arrangeline2 == FIX_BY_HARD) || (mycolormode == CM_LINEART))
1776     arrangeline2 = mycolormode;	/*¿? */
1777   else if ((mycolormode == CM_GRAY) && (hwdcfg->highresolution == FALSE))
1778     arrangeline2 = 0;
1779 
1780   if (hwdcfg->highresolution == FALSE)
1781     {
1782       /* resolution < 1200 dpi */
1783       dev->scanning->arrange_hres = FALSE;
1784       dev->scanning->arrange_sensor_evenodd_dist = 0;
1785     }
1786   else
1787     {
1788       /* resolution > 1200 dpi */
1789       dev->scanning->arrange_hres = TRUE;
1790       dev->scanning->arrange_sensor_evenodd_dist =
1791 	hwdcfg->sensorevenodddistance;
1792     }
1793 
1794   /* with must be adjusted to fit in the dots count per block */
1795   aditional_dots = 0;
1796   if (mycolormode != CM_LINEART)
1797     {
1798       dots_per_block = ((scan2.resolution_x > 2400)
1799 			&& (scancfg->samplerate == PIXEL_RATE)) ? 8 : 4;
1800 
1801       /* fit width */
1802       if ((mycoords.width % dots_per_block) != 0)
1803 	{
1804 	  aditional_dots = dots_per_block - (mycoords.width % dots_per_block);
1805 	  mycoords.width += aditional_dots;
1806 	}
1807     }
1808   else
1809     {
1810       /* Lineart */
1811       dots_per_block = 32 - (mycoords.width & 0x1f);
1812       if (dots_per_block < 32)
1813 	{
1814 	  mycoords.width += dots_per_block;
1815 	  aditional_dots = (dots_per_block / 8);
1816 	}
1817     }
1818 
1819   DBG (DBG_FNC, " -> dots_per_block: %i\n", dots_per_block);
1820   DBG (DBG_FNC, " -> aditional_dots: %i\n", aditional_dots);
1821 
1822   if (mycolormode == CM_LINEART)
1823     {
1824       bytesperline =
1825 	(dev->scanmodes[mymode]->samplerate ==
1826 	 PIXEL_RATE) ? mycoords.width / 4 : mycoords.width / 8;
1827       imagewidth3 = bytesperline;
1828       lineart_width = bytesperline * 8;
1829       line_size = bytesperline - aditional_dots;
1830       dev->Resize->fromwidth = line_size * 8;
1831     }
1832   else
1833     {
1834       /*4510 */
1835       switch (mycolormode)
1836 	{
1837 	case CM_COLOR:
1838 	  channel_count = 3;
1839 	  break;
1840 	case 3:
1841 	  channel_count = 1;
1842 	  break;
1843 	case CM_GRAY:
1844 	  channel_count = (dev->scanmodes[mymode]->samplerate == PIXEL_RATE) ? 2 : 1;	/*1 */
1845 	  break;
1846 	}
1847 
1848       channel_size = (scan2.depth == 8) ? 1 : 2;
1849       bytesperline = mycoords.width * (channel_count * channel_size);
1850       imagewidth3 = bytesperline / channel_count;
1851       lineart_width = imagewidth3 / channel_size;
1852       line_size =
1853 	bytesperline - (aditional_dots * (channel_count * channel_size));
1854       dev->Resize->fromwidth = line_size / (channel_count * channel_size);
1855     }
1856 
1857   imagesize = mycoords.height * bytesperline;
1858   v15b4 = 0;
1859   dev->scanning->arrange_size = imagesize;
1860   v15bc = 0;
1861 
1862   /* set resolution ratio */
1863   data_bitset (&Regs[0xc0], 0x1f,
1864 	       scancfg->sensorresolution / scancfg->resolution_x);
1865 
1866   scancfg->coord.left = mycoords.left;
1867   scancfg->coord.top = mycoords.top;
1868   scancfg->coord.width = mycoords.width;
1869   scancfg->coord.height = mycoords.height;
1870   scancfg->resolution_x = scan2.resolution_x;
1871   scancfg->resolution_y = scan2.resolution_y;
1872 
1873   myvalue =
1874     (dev->Resize->type == RSZ_NONE) ? line_size : dev->Resize->bytesperline;
1875   scancfg->bytesperline = bytesperline;
1876 
1877   scancfg->v157c = myvalue;
1878 
1879   if (scan.colormode != CM_COLOR)
1880     {
1881       if (mycolormode == CM_COLOR)
1882 	scancfg->v157c = (scancfg->v157c / 3);
1883     }
1884 
1885   if (scan.colormode == CM_LINEART)
1886     {
1887       if (mycolormode == 3)
1888 	{
1889 	  scancfg->v157c = (scancfg->v157c + 7) / 8;
1890 	  scancfg->bytesperline = (scancfg->bytesperline + 7) / 8;
1891 	}
1892     }
1893 
1894   DBG (DBG_FNC, "- SetScanParams:\n");
1895 
1896   return OK;
1897 }
1898 
1899 static SANE_Int
GainOffset_Counter_Save(struct st_device * dev,SANE_Byte data)1900 GainOffset_Counter_Save (struct st_device *dev, SANE_Byte data)
1901 {
1902   SANE_Int rst = OK;
1903 
1904   DBG (DBG_FNC, "> GainOffset_Counter_Save(data=%i):\n", data);
1905 
1906   /* check if chipset supports accessing eeprom */
1907   if ((dev->chipset->capabilities & CAP_EEPROM) != 0)
1908     {
1909       data = min (data, 0x0f);
1910       rst = RTS_EEPROM_WriteByte (dev->usb_handle, 0x0077, data);
1911     }
1912 
1913   return rst;
1914 }
1915 
1916 static SANE_Int
GainOffset_Counter_Inc(struct st_device * dev,SANE_Int * arg1)1917 GainOffset_Counter_Inc (struct st_device *dev, SANE_Int * arg1)
1918 {
1919   SANE_Byte count;
1920   SANE_Int rst;
1921 
1922   DBG (DBG_FNC, "+ GainOffset_Counter_Inc:\n");
1923 
1924   /* check if chipset supports accessing eeprom */
1925   if ((dev->chipset->capabilities & CAP_EEPROM) != 0)
1926     {
1927       count = GainOffset_Counter_Load (dev);
1928       if ((count >= 0x0f) || (GainOffset_Get (dev) != OK))
1929 	{
1930 	  offset[CL_BLUE] = offset[CL_GREEN] = offset[CL_RED] = 0;
1931 	  gain[CL_BLUE] = gain[CL_GREEN] = gain[CL_RED] = 0;
1932 	  count = 0;
1933 	}
1934       else
1935 	{
1936 	  count++;
1937 	  if (arg1 != NULL)
1938 	    *arg1 = 1;
1939 	}
1940 
1941       rst = GainOffset_Counter_Save (dev, count);
1942     }
1943   else
1944     rst = OK;
1945 
1946   DBG (DBG_FNC, "- GainOffset_Counter_Inc: %i\n", rst);
1947 
1948   return rst;
1949 }
1950 
1951 static SANE_Int
GainOffset_Get(struct st_device * dev)1952 GainOffset_Get (struct st_device *dev)
1953 {
1954   SANE_Int a, data, rst;
1955   SANE_Byte checksum;
1956 
1957   DBG (DBG_FNC, "+ GainOffset_Get:\n");
1958 
1959   checksum = 0;
1960 
1961   /* check if chipset supports accessing eeprom */
1962   if ((dev->chipset->capabilities & CAP_EEPROM) != 0)
1963     {
1964       /* get current checksum */
1965       if (RTS_EEPROM_ReadByte (dev->usb_handle, 0x76, &checksum) == OK)
1966 	{
1967 	  rst = OK;
1968 
1969 	  /* read gain and offset values from EEPROM */
1970 	  for (a = CL_RED; a <= CL_BLUE; a++)
1971 	    {
1972 	      if (RTS_EEPROM_ReadWord (dev->usb_handle, 0x70 + (2 * a), &data)
1973 		  == ERROR)
1974 		{
1975 		  rst = ERROR;
1976 		  break;
1977 		}
1978 	      else
1979 		offset[a] = data;
1980 	    }
1981 
1982 	  /* check checksum */
1983 	  checksum =
1984 	    _B0 (checksum + offset[CL_GREEN] + offset[CL_BLUE] +
1985 		 offset[CL_RED]);
1986 	}
1987       else
1988 	rst = ERROR;
1989     }
1990   else
1991     rst = ERROR;
1992 
1993   /* extract gain and offset values */
1994   if ((rst == OK) && (checksum == 0x5b))
1995     {
1996       for (a = CL_RED; a <= CL_BLUE; a++)
1997 	{
1998 	  gain[a] = (offset[a] >> 9) & 0x1f;
1999 	  offset[a] &= 0x01ff;
2000 	}
2001     }
2002   else
2003     {
2004       /* null values, let's reset them */
2005       for (a = CL_RED; a <= CL_BLUE; a++)
2006 	{
2007 	  gain[a] = 0;
2008 	  offset[a] = 0;
2009 	}
2010 
2011       rst = ERROR;
2012     }
2013 
2014   DBG (DBG_FNC,
2015        "->   Preview gainR=%i, gainG=%i, gainB=%i, offsetR=%i, offsetG=%i, offsetB=%i\n",
2016        gain[CL_RED], gain[CL_GREEN], gain[CL_BLUE], offset[CL_RED],
2017        offset[CL_GREEN], offset[CL_BLUE]);
2018 
2019   DBG (DBG_FNC, "- GainOffset_Get: %i\n", rst);
2020 
2021   return rst;
2022 }
2023 
2024 static SANE_Int
Scanmode_maxres(struct st_device * dev,SANE_Int scantype,SANE_Int colormode)2025 Scanmode_maxres (struct st_device *dev, SANE_Int scantype, SANE_Int colormode)
2026 {
2027   /* returns position in scanmodes table where data fits with given arguments */
2028   SANE_Int rst = 0;
2029   SANE_Int a;
2030   struct st_scanmode *reg;
2031 
2032   for (a = 0; a < dev->scanmodes_count; a++)
2033     {
2034       reg = dev->scanmodes[a];
2035       if (reg != NULL)
2036 	{
2037 	  if ((reg->scantype == scantype) && (reg->colormode == colormode))
2038 	    rst = max (rst, reg->resolution);	/* found ! */
2039 	}
2040     }
2041 
2042   if (rst == 0)
2043     {
2044       /* There isn't any mode for these arguments.
2045          Most devices doesn't support specific setup to scan in lineart mode
2046          so they use gray colormode. Lets check this case */
2047       if (colormode == CM_LINEART)
2048 	rst = Scanmode_maxres (dev, scantype, CM_GRAY);
2049     }
2050 
2051   DBG (DBG_FNC, "> Scanmode_maxres(scantype=%s, colormode=%s): %i\n",
2052        dbg_scantype (scantype), dbg_colour (colormode), rst);
2053 
2054   return rst;
2055 }
2056 
2057 static SANE_Int
Scanmode_minres(struct st_device * dev,SANE_Int scantype,SANE_Int colormode)2058 Scanmode_minres (struct st_device *dev, SANE_Int scantype, SANE_Int colormode)
2059 {
2060   /* returns position in scanmodes table where data fits with given arguments */
2061   SANE_Int rst, a;
2062   struct st_scanmode *reg;
2063 
2064   rst = Scanmode_maxres (dev, scantype, colormode);
2065 
2066   for (a = 0; a < dev->scanmodes_count; a++)
2067     {
2068       reg = dev->scanmodes[a];
2069       if (reg != NULL)
2070 	{
2071 	  if ((reg->scantype == scantype) && (reg->colormode == colormode))
2072 	    rst = min (rst, reg->resolution);	/* found ! */
2073 	}
2074     }
2075 
2076   if (rst == 0)
2077     {
2078       /* There isn't any mode for these arguments.
2079          Most devices doesn't support specific setup to scan in lineart mode
2080          so they use gray colormode. Lets check this case */
2081       if (colormode == CM_LINEART)
2082 	rst = Scanmode_minres (dev, scantype, CM_GRAY);
2083     }
2084 
2085   DBG (DBG_FNC, "> Scanmode_minres(scantype=%s, colormode=%s): %i\n",
2086        dbg_scantype (scantype), dbg_colour (colormode), rst);
2087 
2088   return rst;
2089 }
2090 
2091 static SANE_Int
Scanmode_fitres(struct st_device * dev,SANE_Int scantype,SANE_Int colormode,SANE_Int resolution)2092 Scanmode_fitres (struct st_device *dev, SANE_Int scantype, SANE_Int colormode,
2093 		 SANE_Int resolution)
2094 {
2095   /* returns a supported resolution */
2096   SANE_Int rst;
2097   SANE_Int a, nullres;
2098   struct st_scanmode *reg;
2099 
2100   nullres = Scanmode_maxres (dev, scantype, colormode) + 1;
2101   rst = nullres;
2102 
2103   for (a = 0; a < dev->scanmodes_count; a++)
2104     {
2105       reg = dev->scanmodes[a];
2106       if (reg != NULL)
2107 	{
2108 	  if ((reg->scantype == scantype) && (reg->colormode == colormode))
2109 	    {
2110 	      if ((reg->resolution < rst) && (resolution <= reg->resolution))
2111 		rst = reg->resolution;
2112 	    }
2113 	}
2114     }
2115 
2116   if (rst == nullres)
2117     {
2118       /* There isn't any mode for these arguments.
2119          Most devices doesn't support specific setup to scan in lineart mode
2120          so they use gray colormode. Lets check this case */
2121       if (colormode != CM_LINEART)
2122 	{
2123 	  /* at this point, given resolution is bigger than maximum supported resolution */
2124 	  rst = -1;
2125 	}
2126       else
2127 	rst = Scanmode_minres (dev, scantype, CM_GRAY);
2128     }
2129 
2130   DBG (DBG_FNC,
2131        "> Scanmode_fitres(scantype=%s, colormode=%s, resolution=%i): %i\n",
2132        dbg_scantype (scantype), dbg_colour (colormode), resolution, rst);
2133 
2134   return rst;
2135 }
2136 
2137 static SANE_Int
RTS_GetScanmode(struct st_device * dev,SANE_Int scantype,SANE_Int colormode,SANE_Int resolution)2138 RTS_GetScanmode (struct st_device *dev, SANE_Int scantype, SANE_Int colormode,
2139 		 SANE_Int resolution)
2140 {
2141   /* returns position in scanmodes table where data fits with given arguments */
2142   SANE_Int rst = -1;
2143   SANE_Int a;
2144   struct st_scanmode *reg;
2145 
2146   for (a = 0; a < dev->scanmodes_count; a++)
2147     {
2148       reg = dev->scanmodes[a];
2149       if (reg != NULL)
2150 	{
2151 	  if ((reg->scantype == scantype) && (reg->colormode == colormode)
2152 	      && (reg->resolution == resolution))
2153 	    {
2154 	      /* found ! */
2155 	      rst = a;
2156 	      break;
2157 	    }
2158 	}
2159     }
2160 
2161   if (rst == -1)
2162     {
2163       /* There isn't any mode for these arguments.
2164          May be given resolution isn't supported by chipset.
2165          Most devices doesn't support specific setup to scan in lineart mode
2166          so they use gray colormode. Lets check this case */
2167       if ((colormode == CM_LINEART) || (colormode == 3))
2168 	rst = RTS_GetScanmode (dev, scantype, CM_GRAY, resolution);
2169     }
2170 
2171   DBG (DBG_FNC,
2172        "> RTS_GetScanmode(scantype=%s, colormode=%s, resolution=%i): %i\n",
2173        dbg_scantype (scantype), dbg_colour (colormode), resolution, rst);
2174 
2175   return rst;
2176 }
2177 
2178 static void
Free_Motor(struct st_device * dev)2179 Free_Motor (struct st_device *dev)
2180 {
2181   /* this function releases space for stepper motor */
2182 
2183   DBG (DBG_FNC, "> Free_Motor\n");
2184 
2185   if (dev->motorcfg != NULL)
2186     {
2187       free (dev->motorcfg);
2188       dev->motorcfg = NULL;
2189     }
2190 }
2191 
2192 static SANE_Int
Load_Motor(struct st_device * dev)2193 Load_Motor (struct st_device *dev)
2194 {
2195   /* this function loads general configuration for motor */
2196 
2197   SANE_Int rst = ERROR;
2198 
2199   DBG (DBG_FNC, "> Load_Motor\n");
2200 
2201   if (dev->motorcfg != NULL)
2202     Free_Motor (dev);
2203 
2204   dev->motorcfg = malloc (sizeof (struct st_motorcfg));
2205   if (dev->motorcfg != NULL)
2206     {
2207       rst = cfg_motor_get (dev->motorcfg);
2208       dbg_motorcfg (dev->motorcfg);
2209     }
2210 
2211   return rst;
2212 }
2213 
2214 static void
Free_Sensor(struct st_device * dev)2215 Free_Sensor (struct st_device *dev)
2216 {
2217   /* this function releases space for ccd sensor */
2218 
2219   DBG (DBG_FNC, "> Free_Sensor\n");
2220 
2221   if (dev->sensorcfg != NULL)
2222     {
2223       free (dev->sensorcfg);
2224       dev->sensorcfg = NULL;
2225     }
2226 }
2227 
2228 static void
Free_Buttons(struct st_device * dev)2229 Free_Buttons (struct st_device *dev)
2230 {
2231   /* this function releases space for buttons */
2232 
2233   DBG (DBG_FNC, "> Free_Buttons\n");
2234 
2235   if (dev->buttons != NULL)
2236     {
2237       free (dev->buttons);
2238       dev->buttons = NULL;
2239     }
2240 }
2241 
2242 static SANE_Int
Load_Buttons(struct st_device * dev)2243 Load_Buttons (struct st_device *dev)
2244 {
2245   /* this function loads configuration for ccd sensor */
2246 
2247   SANE_Int rst = ERROR;
2248 
2249   DBG (DBG_FNC, "> Load_Buttons\n");
2250 
2251   if (dev->buttons != NULL)
2252     Free_Buttons (dev);
2253 
2254   dev->buttons = malloc (sizeof (struct st_buttons));
2255   if (dev->buttons != NULL)
2256     {
2257       rst = cfg_buttons_get (dev->buttons);
2258       dbg_buttons (dev->buttons);
2259     }
2260 
2261   return rst;
2262 }
2263 
2264 static SANE_Int
Load_Sensor(struct st_device * dev)2265 Load_Sensor (struct st_device *dev)
2266 {
2267   /* this function loads configuration for ccd sensor */
2268 
2269   SANE_Int rst = ERROR;
2270 
2271   DBG (DBG_FNC, "> Load_Sensor\n");
2272 
2273   if (dev->sensorcfg != NULL)
2274     Free_Sensor (dev);
2275 
2276   dev->sensorcfg = malloc (sizeof (struct st_sensorcfg));
2277   if (dev->sensorcfg != NULL)
2278     {
2279       rst = cfg_sensor_get (dev->sensorcfg);
2280       dbg_sensor (dev->sensorcfg);
2281     }
2282 
2283   return rst;
2284 }
2285 
2286 static void
Free_Timings(struct st_device * dev)2287 Free_Timings (struct st_device *dev)
2288 {
2289   /* this function frees all ccd sensor timing tables */
2290   DBG (DBG_FNC, "> Free_Timings\n");
2291 
2292   if (dev->timings != NULL)
2293     {
2294       if (dev->timings_count > 0)
2295 	{
2296 	  SANE_Int a;
2297 	  for (a = 0; a < dev->timings_count; a++)
2298 	    if (dev->timings[a] != NULL)
2299 	      free (dev->timings[a]);
2300 
2301 	  dev->timings_count = 0;
2302 	}
2303 
2304       free (dev->timings);
2305       dev->timings = NULL;
2306     }
2307 }
2308 
2309 static SANE_Int
Load_Timings(struct st_device * dev)2310 Load_Timings (struct st_device *dev)
2311 {
2312   SANE_Int rst = OK;
2313   SANE_Int a;
2314   struct st_timing reg, *tmg;
2315 
2316   DBG (DBG_FNC, "> Load_Timings\n");
2317 
2318   if (dev->timings != NULL)
2319     Free_Timings (dev);
2320 
2321   a = 0;
2322 
2323   while ((cfg_timing_get (dev->sensorcfg->type, a, &reg) == OK)
2324 	 && (rst == OK))
2325     {
2326       tmg = (struct st_timing *) malloc (sizeof (struct st_timing));
2327       if (tmg != NULL)
2328 	{
2329 	  memcpy (tmg, &reg, sizeof (struct st_timing));
2330 
2331 	  dev->timings_count++;
2332 	  dev->timings =
2333 	    (struct st_timing **) realloc (dev->timings,
2334 					   sizeof (struct st_timing **) *
2335 					   dev->timings_count);
2336 	  if (dev->timings == NULL)
2337 	    {
2338 	      rst = ERROR;
2339 	      dev->timings_count = 0;
2340 	    }
2341 	  else
2342 	    dev->timings[dev->timings_count - 1] = tmg;
2343 	}
2344       else
2345 	rst = ERROR;
2346 
2347       a++;
2348     }
2349 
2350   if (rst == ERROR)
2351     Free_Timings (dev);
2352 
2353   DBG (DBG_FNC, " -> Found %i timing registers\n", dev->timings_count);
2354 
2355   return rst;
2356 }
2357 
2358 static SANE_Int
IsScannerLinked(struct st_device * dev)2359 IsScannerLinked (struct st_device *dev)
2360 {
2361   SANE_Int var2;
2362   SANE_Byte lamp;
2363 
2364   DBG (DBG_FNC, "+ IsScannerLinked:\n");
2365 
2366   Read_FE3E (dev, &v1619);
2367   Init_USBData (dev);
2368   scan.scantype = ST_NORMAL;
2369 
2370   RTS_WaitInitEnd (dev, 0x30000);
2371 
2372   lamp = FLB_LAMP;
2373 
2374   /* Comprobar si es la primera conexión con el escaner */
2375   if (Read_Word (dev->usb_handle, 0xe829, &var2) == OK)
2376     {
2377       SANE_Int firstconnection;
2378 
2379 #ifdef STANDALONE
2380       firstconnection = TRUE;
2381 #else
2382       firstconnection = (var2 == 0) ? TRUE : FALSE;
2383 #endif
2384 
2385       if (firstconnection == TRUE)
2386 	{
2387 	  /* primera conexión */
2388 	  SANE_Byte flb_lamp, tma_lamp;
2389 
2390 	  flb_lamp = 0;
2391 	  tma_lamp = 0;
2392 	  Lamp_Status_Get (dev, &flb_lamp, &tma_lamp);
2393 
2394 	  if ((flb_lamp == 0) && (tma_lamp != 0))
2395 	    lamp = TMA_LAMP;
2396 
2397 	  /*Clear GainOffset count */
2398 	  GainOffset_Clear (dev);
2399 	  GainOffset_Counter_Save (dev, 0);
2400 
2401 	  /* Clear AutoRef count */
2402 	  Refs_Counter_Save (dev, 0);
2403 
2404 	  Buttons_Enable (dev);
2405 	  Lamp_Status_Timer_Set (dev, 13);
2406 	}
2407       else
2408 	lamp = (_B0 (var2) == 0) ? FLB_LAMP : TMA_LAMP;
2409     }
2410 
2411   if (RTS_Warm_Reset (dev) != OK)
2412     return ERROR;
2413 
2414   Head_ParkHome (dev, TRUE, dev->motorcfg->parkhomemotormove);
2415 
2416   Lamp_Status_Timer_Set (dev, 13);
2417 
2418   /* Use fixed pwm? */
2419   if (RTS_Debug->use_fixed_pwm != FALSE)
2420     {
2421       Lamp_PWM_Save (dev, cfg_fixedpwm_get (dev->sensorcfg->type, ST_NORMAL));
2422       /* Lets enable using fixed pwm */
2423       Lamp_PWM_SaveStatus (dev, TRUE);
2424     }
2425 
2426   Lamp_PWM_Setup (dev, lamp);
2427 
2428   DBG (DBG_FNC, "- IsScannerLinked:\n");
2429 
2430   return OK;
2431 }
2432 
2433 static SANE_Int
Lamp_PWM_SaveStatus(struct st_device * dev,SANE_Byte status)2434 Lamp_PWM_SaveStatus (struct st_device *dev, SANE_Byte status)
2435 {
2436   SANE_Byte mypwm;
2437   SANE_Int rst = OK;
2438 
2439   DBG (DBG_FNC, "+ Lamp_PWM_SaveStatus(status=%i):\n", status);
2440 
2441   /* check if chipset supports accessing eeprom */
2442   if ((dev->chipset->capabilities & CAP_EEPROM) != 0)
2443     {
2444       rst = ERROR;
2445 
2446       if (RTS_EEPROM_ReadByte (dev->usb_handle, 0x007b, &mypwm) == OK)
2447 	{
2448 	  mypwm = (status == FALSE) ? mypwm & 0x7f : mypwm | 0x80;
2449 
2450 	  if (RTS_EEPROM_WriteByte (dev->usb_handle, 0x007b, mypwm) == OK)
2451 	    rst = OK;
2452 	}
2453     }
2454 
2455   DBG (DBG_FNC, "- Lamp_PWM_SaveStatus: %i\n", rst);
2456 
2457   return rst;
2458 }
2459 
2460 static SANE_Int
Lamp_PWM_Save(struct st_device * dev,SANE_Int fixedpwm)2461 Lamp_PWM_Save (struct st_device *dev, SANE_Int fixedpwm)
2462 {
2463   SANE_Int rst;
2464 
2465   DBG (DBG_FNC, "+ Lamp_PWM_Save(fixedpwm=%i):\n", fixedpwm);
2466 
2467   /* check if chipset supports accessing eeprom */
2468   if ((dev->chipset->capabilities & CAP_EEPROM) != 0)
2469     rst =
2470       RTS_EEPROM_WriteByte (dev->usb_handle, 0x7b, ((fixedpwm << 2) | 0x80));
2471   else
2472     rst = OK;
2473 
2474   DBG (DBG_FNC, "- Lamp_PWM_Save: %i\n", rst);
2475 
2476   return rst;
2477 }
2478 
2479 static SANE_Int
Lamp_PWM_Setup(struct st_device * dev,SANE_Int lamp)2480 Lamp_PWM_Setup (struct st_device *dev, SANE_Int lamp)
2481 {
2482   SANE_Int rst = OK;
2483 
2484   DBG (DBG_FNC, "+ Lamp_PWM_Setup(lamp=%s):\n",
2485        (lamp == FLB_LAMP) ? "FLB_LAMP" : "TMA_LAMP");
2486 
2487   if (Lamp_PWM_use (dev, 1) == OK)
2488     {
2489       SANE_Int fixedpwm, currentpwd;
2490 
2491       currentpwd = 0;
2492       fixedpwm =
2493 	cfg_fixedpwm_get (dev->sensorcfg->type,
2494 			  (lamp == FLB_LAMP) ? ST_NORMAL : ST_TA);
2495 
2496       if (Lamp_PWM_DutyCycle_Get (dev, &currentpwd) == OK)
2497 	{
2498 	  /* set duty cycle if current one is different */
2499 	  if (currentpwd != fixedpwm)
2500 	    rst = Lamp_PWM_DutyCycle_Set (dev, fixedpwm);
2501 	}
2502       else
2503 	rst = Lamp_PWM_DutyCycle_Set (dev, fixedpwm);
2504     }
2505 
2506   DBG (DBG_FNC, "- Lamp_PWM_Setup: %i\n", rst);
2507 
2508   return rst;
2509 }
2510 
2511 static SANE_Int
Lamp_PWM_DutyCycle_Get(struct st_device * dev,SANE_Int * data)2512 Lamp_PWM_DutyCycle_Get (struct st_device *dev, SANE_Int * data)
2513 {
2514   SANE_Byte a;
2515   SANE_Int rst = ERROR;
2516 
2517   DBG (DBG_FNC, "+ Lamp_PWM_DutyCycle_Get:\n");
2518 
2519   if (Read_Byte (dev->usb_handle, 0xe948, &a) == OK)
2520     {
2521       *data = a & 0x3f;
2522       rst = OK;
2523     }
2524 
2525   DBG (DBG_FNC, "- Lamp_PWM_DutyCycle_Get = %i: %i\n", *data, rst);
2526 
2527   return rst;
2528 }
2529 
2530 static SANE_Int
Lamp_PWM_DutyCycle_Set(struct st_device * dev,SANE_Int duty_cycle)2531 Lamp_PWM_DutyCycle_Set (struct st_device *dev, SANE_Int duty_cycle)
2532 {
2533   SANE_Byte *Regs;
2534   SANE_Int rst;
2535 
2536   DBG (DBG_FNC, "+ Lamp_PWM_DutyCycle_Set(duty_cycle=%i):\n", duty_cycle);
2537 
2538   rst = ERROR;
2539 
2540   Regs = (SANE_Byte *) malloc (RT_BUFFER_LEN * sizeof (SANE_Byte));
2541   if (Regs != NULL)
2542     {
2543       if (RTS_ReadRegs (dev->usb_handle, Regs) == OK)
2544 	{
2545 	  data_bitset (&Regs[0x148], 0x3f, duty_cycle);
2546 
2547 	  if (pwmlamplevel == 0)
2548 	    {
2549 	      data_bitset (&Regs[0x148], 0x40, 0);
2550 	      Regs[0x1e0] |= ((duty_cycle >> 1) & 0x40);
2551 	    }
2552 
2553 	  data_bitset (&dev->init_regs[0x148], 0x7f, Regs[0x148]);
2554 	  data_bitset (&dev->init_regs[0x1e0], 0x3f, Regs[0x1e0]);
2555 
2556 	  Write_Byte (dev->usb_handle, 0xe948, Regs[0x0148]);
2557 
2558 	  rst = Write_Byte (dev->usb_handle, 0xe9e0, Regs[0x01e0]);
2559 	}
2560 
2561       free (Regs);
2562     }
2563 
2564   DBG (DBG_FNC, "- Lamp_PWM_DutyCycle_Set: %i\n", rst);
2565 
2566   return rst;
2567 }
2568 
2569 static SANE_Int
Head_ParkHome(struct st_device * dev,SANE_Int bWait,SANE_Int movement)2570 Head_ParkHome (struct st_device *dev, SANE_Int bWait, SANE_Int movement)
2571 {
2572   SANE_Int rst = ERROR;
2573   SANE_Byte *Regs;
2574 
2575   DBG (DBG_FNC, "+ Head_ParkHome(bWait=%i, movement=%i):\n", bWait, movement);
2576 
2577   Regs = (SANE_Byte *) malloc (RT_BUFFER_LEN * sizeof (SANE_Byte));
2578   if (Regs != NULL)
2579     {
2580       rst = OK;
2581 
2582       memcpy (Regs, dev->init_regs, RT_BUFFER_LEN * sizeof (SANE_Byte));
2583 
2584       /* Lets wait if it's required when is already executing */
2585       if (bWait != FALSE)
2586 	{
2587 	  if (RTS_WaitScanEnd (dev, 0x3a98) != OK)
2588 	    {
2589 	      DBG (DBG_FNC, " -> Head_ParkHome: RTS_WaitScanEnd Timeout\n");
2590 	      rst = ERROR;	/* timeout */
2591 	    }
2592 	}
2593       else
2594 	{
2595 	  if (RTS_IsExecuting (dev, Regs) == FALSE)
2596 	    {
2597 	      DBG (DBG_FNC,
2598 		   " -> Head_ParkHome: RTS_IsExecuting = 0, exiting function\n");
2599 	      rst = ERROR;	/* if NOT executing */
2600 	    }
2601 	}
2602 
2603       /* Check if lamp is at home */
2604       if ((rst == OK) && (Head_IsAtHome (dev, Regs) == FALSE))
2605 	{
2606 	  struct st_motormove mymotor;
2607 	  struct st_motorpos mtrpos;
2608 
2609 	  DBG (DBG_FNC,
2610 	       "->   Head_ParkHome: Lamp is not at home, lets move\n");
2611 
2612 	  /* it isn't */
2613 	  dev->status->parkhome = TRUE;
2614 
2615 	  if ((movement != -1) && (movement < dev->motormove_count))
2616 	    {
2617 	      memcpy (&mymotor, dev->motormove[movement],
2618 		      sizeof (struct st_motormove));
2619 	    }
2620 	  else
2621 	    {
2622 	      /* debug this code. Shouldn't have any relationship with offsets */
2623 	      if (default_gain_offset->edcg2[CL_BLUE] < 4)
2624 		mymotor.scanmotorsteptype =
2625 		  default_gain_offset->edcg2[CL_BLUE];
2626 
2627 	      mymotor.ctpc = default_gain_offset->odcg2[1];
2628 	      mymotor.systemclock = default_gain_offset->edcg2[1];	/*? */
2629 	    }
2630 
2631 	  mtrpos.options = MTR_ENABLED | MTR_BACKWARD;
2632 	  mtrpos.v12e448 = 0x01;
2633 	  mtrpos.v12e44c = 0x00;
2634 	  mtrpos.coord_y = 0x4e20;
2635 
2636 	  Motor_Move (dev, Regs, &mymotor, &mtrpos);
2637 
2638 	  /* Should we wait? */
2639 	  if (bWait != FALSE)
2640 	    rst = RTS_WaitScanEnd (dev, 15000);
2641 
2642 	  dev->status->parkhome = FALSE;
2643 	}
2644 
2645       free (Regs);
2646     }
2647 
2648   DBG (DBG_FNC, "- Head_ParkHome: %i:\n", rst);
2649 
2650   return rst;
2651 }
2652 
2653 static SANE_Int
Motor_Move(struct st_device * dev,SANE_Byte * Regs,struct st_motormove * mymotor,struct st_motorpos * mtrpos)2654 Motor_Move (struct st_device *dev, SANE_Byte * Regs,
2655 	    struct st_motormove *mymotor, struct st_motorpos *mtrpos)
2656 {
2657   SANE_Byte *cpRegs;
2658   SANE_Int rst;
2659 
2660   DBG (DBG_FNC, "+ Motor_Move:\n");
2661 
2662   rst = ERROR;
2663 
2664   cpRegs = (SANE_Byte *) malloc (RT_BUFFER_LEN * sizeof (SANE_Byte));
2665   if (cpRegs != NULL)
2666     {
2667       SANE_Int data, v12dcf8, coord_y, step_type;
2668 
2669       memcpy (cpRegs, Regs, RT_BUFFER_LEN * sizeof (SANE_Byte));
2670       v12dcf8 = 0;
2671 
2672       /* resolution = 1 dpi */
2673       data_bitset (&cpRegs[0xc0], 0x1f, 1);	     /*---xxxxx*/
2674 
2675       /* set motor step type */
2676       data_bitset (&cpRegs[0xd9], 0x70, mymotor->scanmotorsteptype);	      /*-xxx----*/
2677 
2678       /* set motor direction (polarity) */
2679       data_bitset (&cpRegs[0xd9], 0x80, mtrpos->options >> 3);	/*e------- */
2680 
2681       /* next value doesn't seem to have any effect */
2682       data_bitset (&cpRegs[0xd9], 0x0f, mtrpos->options);		       /*----efgh*/
2683 
2684       /* 0 enable/1 disable motor */
2685       data_bitset (&cpRegs[0xdd], 0x80, mtrpos->options >> 4);	/*d------- */
2686 
2687       /* next value doesn't seem to have any effect */
2688       data_bitset (&cpRegs[0xdd], 0x40, mtrpos->options >> 4);		       /*-d------*/
2689 
2690       switch (mymotor->scanmotorsteptype)
2691 	{
2692 	case STT_OCT:
2693 	  step_type = 8;
2694 	  break;
2695 	case STT_QUART:
2696 	  step_type = 4;
2697 	  break;
2698 	case STT_HALF:
2699 	  step_type = 2;
2700 	  break;
2701 	case STT_FULL:
2702 	  step_type = 1;
2703 	  break;
2704 	default:
2705 	  step_type = 0;
2706 	  break;		/* shouldn't be used */
2707 	}
2708 
2709       coord_y = (mtrpos->coord_y * step_type) & 0xffff;
2710       if (coord_y < 2)
2711 	coord_y = 2;
2712 
2713       /* Sets dummyline to 1 */
2714       data_bitset (&cpRegs[0xd6], 0xf0, 1);
2715 
2716       /* set step_size - 1 */
2717       cpRegs[0xe0] = 0;
2718 
2719       cpRegs[0x01] &= 0xf9;
2720       cpRegs[0x01] |= (mtrpos->v12e448 & 1) << 2;
2721 
2722       /* set dummy scan */
2723       data_bitset (&cpRegs[0x01], 0x10, 1);	     /*---x----*/
2724 
2725       /* set samplerate */
2726       data_bitset (&cpRegs[0x1cf], 0x40, PIXEL_RATE);	       /*-x------*/
2727 
2728       /* unknown data */
2729       data_bitset (&cpRegs[0x1cf], 0x80, 1);	/*x------- */
2730 
2731       /* sets one channel per color */
2732       data_bitset (&cpRegs[0x12], 0x3f, 0);	/* channel   */
2733       data_bitset (&cpRegs[0x12], 0xc0, 1);	/* 1 channel */
2734 
2735       /* timing cnpp */
2736       data_bitset (&cpRegs[0x96], 0x3f, 0x0b);		/*--001011*/
2737 
2738       /* set systemclock */
2739       data_bitset (&cpRegs[0x00], 0x0f, mymotor->systemclock);		/*----xxxx*/
2740 
2741       /* set last step of accurve.smearing table to 2 */
2742       data_lsb_set (&cpRegs[0xe4], 2, 3);
2743 
2744       /* set last step of deccurve.scanbufferfull table to 16 */
2745       data_lsb_set (&Regs[0xea], 0x10, 3);
2746 
2747       /* set last step of deccurve.normalscan table to 16 */
2748       data_lsb_set (&Regs[0xed], 0x10, 3);
2749 
2750       /* set last step of deccurve.smearing table to 16 */
2751       data_lsb_set (&Regs[0xf0], 0x10, 3);
2752 
2753       /* set last step of deccurve.parkhome table to 16 */
2754       data_lsb_set (&Regs[0xf3], 0x10, 3);
2755 
2756       /* set msi */
2757       cpRegs[0xda] = 2;
2758       cpRegs[0xdd] &= 0xfc;
2759 
2760       /* set if motor has motorcurves */
2761       data_bitset (&cpRegs[0xdf], 0x10,
2762 		   ((mymotor->motorcurve != -1) ? 1 : 0));
2763 
2764       if (mymotor->motorcurve != -1)
2765 	{
2766 	  struct st_curve *crv;
2767 
2768 	  /* set last step of accurve.normalscan table */
2769 	  crv =
2770 	    Motor_Curve_Get (dev, mymotor->motorcurve, ACC_CURVE,
2771 			     CRV_NORMALSCAN);
2772 	  if (crv != NULL)
2773 	    data_lsb_set (&cpRegs[0xe1], crv->step[crv->step_count - 1], 3);
2774 
2775 	  DBG (DBG_FNC, " -> Setting up stepper motor using motorcurve %i\n",
2776 	       mymotor->motorcurve);
2777 	  v12dcf8 = Motor_Setup_Steps (dev, cpRegs, mymotor->motorcurve);
2778 
2779 	  /* set step_size - 1 */
2780 	  cpRegs[0xe0] = 0;
2781 
2782 	  crv =
2783 	    Motor_Curve_Get (dev, mymotor->motorcurve, DEC_CURVE,
2784 			     CRV_NORMALSCAN);
2785 	  if (crv != NULL)
2786 	    coord_y -= (v12dcf8 + crv->step_count);
2787 
2788 	  /* set line exposure time */
2789 	  data_lsb_set (&cpRegs[0x30], mymotor->ctpc, 3);
2790 
2791 	  /* set last step of accurve.smearing table */
2792 	  data_lsb_set (&cpRegs[0xe4], 0, 3);
2793 	}
2794       else
2795 	{
2796 	  /* Setting some motor step */
2797 	  SANE_Int some_step;
2798 
2799 	  switch (Regs[0x00] & 0x0f)
2800 	    {
2801 	    case 0x00:
2802 	      some_step = 0x00895440;
2803 	      break;		/*  3 x 0x2DC6C0 */
2804 	    case 0x08:
2805 	    case 0x01:
2806 	      some_step = 0x00b71b00;
2807 	      break;		/*  4 x 0x2DC6C0 */
2808 	    case 0x02:
2809 	      some_step = 0x0112a880;
2810 	      break;		/*  6 x 0x2DC6C0 */
2811 	    case 0x0a:
2812 	    case 0x03:
2813 	      some_step = 0x016e3600;
2814 	      break;		/*  8 x 0x2DC6C0 */
2815 	    case 0x04:
2816 	      some_step = 0x02255100;
2817 	      break;		/* 12 x 0x2DC6C0 */
2818 	    case 0x0c:
2819 	      some_step = 0x02dc6c00;
2820 	      break;		/* 16 x 0x2DC6C0 */
2821 	    case 0x05:
2822 	      some_step = 0x044aa200;
2823 	      break;		/* 24 x 0x2DC6C0 */
2824 	    case 0x0d:
2825 	      some_step = 0x05b8d800;
2826 	      break;		/* 32 x 0x2DC6C0 */
2827 
2828 	    case 0x09:
2829 	      some_step = 0x00f42400;
2830 	      break;
2831 	    case 0x0b:
2832 	      some_step = 0x01e84800;
2833 	      break;		/* = case 9 * 2 */
2834 	    default:
2835 	      some_step = 0x0478f7f8;
2836 	      break;
2837 	    }
2838 
2839 	  /* divide by timing.cnpp */
2840 	  some_step /= ((cpRegs[0x96] & 0x3f) + 1);
2841 	  if (mymotor->ctpc > 0)
2842 	    some_step /= mymotor->ctpc;
2843 
2844 	  /* set line exposure time */
2845 	  data_lsb_set (&cpRegs[0x30], some_step, 3);
2846 
2847 	  /* set last step of accurve.normalscan table */
2848 	  data_lsb_set (&cpRegs[0xe1], some_step, 3);
2849 	}
2850 
2851       /* Setting coords */
2852       RTS_Setup_Coords (cpRegs, 100, coord_y - 1, 800, 1);
2853 
2854       /* enable head movement */
2855       data_bitset (&cpRegs[0xd8], 0x80, 1);
2856 
2857       /* release motor before executing */
2858       Motor_Release (dev);
2859 
2860       RTS_Warm_Reset (dev);
2861 
2862       /* action! */
2863       data = RTS_WriteRegs (dev->usb_handle, cpRegs);
2864       if (data == OK)
2865 	RTS_Execute (dev);
2866 
2867       /* wait 10 seconds */
2868       RTS_WaitScanEnd (dev, 10000);
2869 
2870       rst = (data != OK) ? v12dcf8 : RTS_WaitScanEnd (dev, 20000);
2871 
2872       free (cpRegs);
2873     }
2874 
2875   DBG (DBG_FNC, "- Motor_Move: %i\n", rst);
2876 
2877   return rst;
2878 }
2879 
2880 static void
Free_Motormoves(struct st_device * dev)2881 Free_Motormoves (struct st_device *dev)
2882 {
2883   DBG (DBG_FNC, "> Free_Motormoves\n");
2884 
2885   if (dev->motormove != NULL)
2886     {
2887       SANE_Int a;
2888       struct st_motormove *ms;
2889 
2890       for (a = 0; a < dev->motormove_count; a++)
2891 	{
2892 	  ms = dev->motormove[a];
2893 	  if (ms != NULL)
2894 	    free (ms);
2895 	}
2896 
2897       free (dev->motormove);
2898       dev->motormove = NULL;
2899     }
2900 
2901   dev->motormove_count = 0;
2902 }
2903 
2904 static void
Free_MotorCurves(struct st_device * dev)2905 Free_MotorCurves (struct st_device *dev)
2906 {
2907   DBG (DBG_FNC, "> Free_MotorCurves\n");
2908   if (dev->mtrsetting != NULL)
2909     Motor_Curve_Free (dev->mtrsetting, &dev->mtrsetting_count);
2910 
2911   dev->mtrsetting = NULL;
2912   dev->mtrsetting_count = 0;
2913 }
2914 
2915 static SANE_Int
Load_MotorCurves(struct st_device * dev)2916 Load_MotorCurves (struct st_device *dev)
2917 {
2918   SANE_Int rst = ERROR;
2919   SANE_Int *mtc = NULL;
2920 
2921   if (dev->mtrsetting != NULL)
2922     Free_MotorCurves (dev);
2923 
2924   DBG (DBG_FNC, "> Load_MotorCurves\n");
2925 
2926   /* get motor settings buffer for this device */
2927   mtc = cfg_motorcurve_get ();
2928   if (mtc != NULL)
2929     {
2930       /* parse buffer to get all motorcurves */
2931       dev->mtrsetting = Motor_Curve_Parse (&dev->mtrsetting_count, mtc);
2932       if (dev->mtrsetting != NULL)
2933 	rst = OK;
2934     }
2935 
2936   if (rst != ERROR)
2937     {
2938       DBG (DBG_FNC, " -> Found %i motor settings\n", dev->mtrsetting_count);
2939       dbg_motorcurves (dev);
2940     }
2941   else
2942     DBG (DBG_ERR, "- Load_MotorCurves error!!\n");
2943 
2944   return rst;
2945 }
2946 
2947 static SANE_Int
Load_Motormoves(struct st_device * dev)2948 Load_Motormoves (struct st_device *dev)
2949 {
2950   SANE_Int rst = OK;
2951   SANE_Int a;
2952   struct st_motormove reg, *mm;
2953 
2954   DBG (DBG_FNC, "> Load_Motormoves\n");
2955 
2956   /* if there is already any movement loaded let's free it */
2957   if (dev->motormove != NULL)
2958     Free_Motormoves (dev);
2959 
2960   a = 0;
2961   while ((cfg_motormove_get (dev->sensorcfg->type, a, &reg) != ERROR)
2962 	 && (rst == OK))
2963     {
2964       dev->motormove_count++;
2965       dev->motormove =
2966 	(struct st_motormove **) realloc (dev->motormove,
2967 					  sizeof (struct st_motormove **) *
2968 					  dev->motormove_count);
2969       if (dev->motormove != NULL)
2970 	{
2971 	  mm = (struct st_motormove *) malloc (sizeof (struct st_motormove));
2972 	  if (mm != NULL)
2973 	    {
2974 	      memcpy (mm, &reg, sizeof (struct st_motormove));
2975 	      dev->motormove[dev->motormove_count - 1] = mm;
2976 	    }
2977 	  else
2978 	    rst = ERROR;
2979 	}
2980       else
2981 	rst = ERROR;
2982 
2983       a++;
2984     }
2985 
2986   if (rst == ERROR)
2987     Free_Motormoves (dev);
2988 
2989   DBG (DBG_FNC, " -> Found %i motormoves\n", dev->motormove_count);
2990   dbg_motormoves (dev);
2991 
2992   return rst;
2993 }
2994 
2995 static SANE_Byte *
Motor_AddStep(SANE_Byte * steps,SANE_Int * bwriten,SANE_Int step)2996 Motor_AddStep (SANE_Byte * steps, SANE_Int * bwriten, SANE_Int step)
2997 {
2998   steps = (SANE_Byte *) realloc (steps, sizeof (SANE_Byte) * (*bwriten + 3));
2999   if (steps != NULL)
3000     {
3001       data_msb_set (&steps[*bwriten], step, 3);
3002       *bwriten += 3;
3003     }
3004   else
3005     *bwriten = 0;
3006 
3007   return steps;
3008 }
3009 
3010 static SANE_Int
Motor_Setup_Steps(struct st_device * dev,SANE_Byte * Regs,SANE_Int mysetting)3011 Motor_Setup_Steps (struct st_device *dev, SANE_Byte * Regs,
3012 		   SANE_Int mysetting)
3013 {
3014   SANE_Int varx10, cont, last_acc_step, varx20, stepbuffer_size,
3015     mystep, bwriten;
3016   SANE_Int myvar, var1, myvalor, mybwriten;
3017   struct st_curve *mycurve;
3018   SANE_Byte *steps;
3019 
3020   DBG (DBG_FNC, "+ Motor_Setup_Steps(*Regs, motorsetting=%i):\n", mysetting);
3021 
3022   varx10 = 0;
3023   cont = 0;
3024   varx20 = 0;
3025   stepbuffer_size = (v15f8 << 4) & 0xffff;
3026   steps = NULL;
3027   bwriten = 0;
3028   deccurvecount = 0;
3029   acccurvecount = 0;
3030   last_acc_step = 0;
3031 
3032   /* mycurve points to acc normalscan steps table */
3033   mycurve = Motor_Curve_Get (dev, mysetting, ACC_CURVE, CRV_NORMALSCAN);
3034 
3035   if (mycurve != NULL)
3036     {
3037       /* acccurvecount has the number of steps in acc normalscan table */
3038       acccurvecount = mycurve->step_count;
3039 
3040       /* get last acccurve step from acc.normalscan step table */
3041       last_acc_step = data_lsb_get (&Regs[0xe1], 3);
3042 
3043       /* sets pointer to acc.normalscan step table */
3044       data_wide_bitset (&Regs[0xf6], 0x3fff, stepbuffer_size);
3045 
3046       /* Separate each step in three bytes */
3047       if (mycurve->step_count > 0)
3048 	for (cont = 0; cont < mycurve->step_count; cont++)
3049 	  {
3050 	    mystep = mycurve->step[cont];
3051 	    if (mystep <= last_acc_step)
3052 	      {
3053 		acccurvecount = cont;
3054 		break;
3055 	      }
3056 	    varx20 += mystep + 1;
3057 	    steps = Motor_AddStep (steps, &bwriten, mystep);
3058 	  }
3059     }
3060 
3061   if (acccurvecount == 0)
3062     {
3063       /* Write one step (last_acc_step + 0x01) to buffer */
3064       acccurvecount++;
3065       varx20 += (last_acc_step + 1) + 1;
3066       steps = Motor_AddStep (steps, &bwriten, last_acc_step + 1);
3067     }
3068 
3069   /* write another step (last_acc_step) */
3070   acccurvecount++;
3071   varx20 += last_acc_step + 1;
3072   steps = Motor_AddStep (steps, &bwriten, last_acc_step);
3073 
3074   /* get line exposure time */
3075   myvar = data_lsb_get (&Regs[0x30], 3) + 1;
3076 
3077   var1 = (varx20 + myvar - 1) / myvar;
3078   var1 = ((var1 * myvar) + mycurve->step[0] - varx20) - 0x0d;
3079   if (steps != NULL)
3080     data_msb_set (&steps[0], var1, 3);
3081 
3082   /* dec.scanbufferfull step table */
3083   /* set pointer to next table */
3084   stepbuffer_size += (acccurvecount * 3);
3085   data_wide_bitset (&Regs[0xf8], 0x3fff, stepbuffer_size);
3086 
3087   /* set last step of deccurve.scanbufferfull table */
3088   mycurve = Motor_Curve_Get (dev, mysetting, DEC_CURVE, CRV_BUFFERFULL);
3089   deccurvecount = mycurve->step_count;
3090   data_lsb_set (&Regs[0xea], mycurve->step[mycurve->step_count - 1], 3);
3091 
3092   /* write another step mycurve->step_count,cont,last_acc_step */
3093   deccurvecount++;
3094   steps = Motor_AddStep (steps, &bwriten, last_acc_step);
3095 
3096   /* Separate each step in three bytes */
3097   if (mycurve->step_count > 1)
3098     for (cont = 0; cont < (mycurve->step_count - 1); cont++)
3099       {
3100 	mystep = mycurve->step[cont];
3101 	if (mystep > last_acc_step)
3102 	  steps = Motor_AddStep (steps, &bwriten, mystep);
3103 	else
3104 	  deccurvecount--;
3105       }
3106 
3107   myvalor = dev->mtrsetting[mysetting]->motorbackstep;
3108   if (myvalor > 0)
3109     {
3110       SANE_Int step_size = _B0 (Regs[0xe0]) + 1;
3111 
3112       myvalor = ((myvalor - deccurvecount) - acccurvecount) + 2;
3113       varx10 = myvalor;
3114       myvalor /= step_size;
3115       myvalor *= step_size;
3116       var1 = mycurve->step[mycurve->step_count - 1];	/* last deccurve step */
3117       if (last_acc_step >= var1)
3118 	var1 = last_acc_step + 1;
3119       deccurvecount += (varx10 - myvalor);
3120       myvalor = varx10 - myvalor;
3121     }
3122   else
3123     myvalor = varx10;
3124 
3125   if (myvalor > 0)
3126     for (cont = myvalor; cont > 0; cont--)
3127       steps = Motor_AddStep (steps, &bwriten, var1 - 1);
3128 
3129   /* write another step , bwriten tiene 4b */
3130   steps = Motor_AddStep (steps, &bwriten, var1);
3131 
3132   /* acc.smearing step table */
3133   if (Motor_Curve_Get (dev, mysetting, ACC_CURVE, CRV_SMEARING) != NULL)
3134     {
3135       /* acc.smearing curve enabled */
3136       if (Motor_Curve_Equal
3137 	  (dev, mysetting, ACC_CURVE, CRV_SMEARING, CRV_NORMALSCAN) == TRUE)
3138 	{
3139 	  /* acc.smearing pointer points to acc.normalscan table */
3140 	  data_wide_bitset (&Regs[0xfa], 0x3fff,
3141 			    data_lsb_get (&Regs[0xf6], 2));
3142 	  /* last step of acc.smearing table is the same as acc.normalscan */
3143 	  data_lsb_set (&Regs[0xe4], data_lsb_get (&Regs[0xe1], 3), 3);
3144 	}
3145       else
3146 	{
3147 	  /* set pointer to next step table */
3148 	  stepbuffer_size += (deccurvecount * 3);
3149 	  data_wide_bitset (&Regs[0xfa], 0x3fff, stepbuffer_size);
3150 
3151 	  /* set last step of acc.smearing table */
3152 	  mycurve = Motor_Curve_Get (dev, mysetting, ACC_CURVE, CRV_SMEARING);
3153 	  if (mycurve != NULL)
3154 	    {
3155 	      smearacccurvecount = mycurve->step_count;
3156 	      data_lsb_set (&Regs[0xe4],
3157 			    mycurve->step[mycurve->step_count - 1], 3);
3158 
3159 	      /* generate acc.smearing table */
3160 	      if (mycurve->step_count > 0)
3161 		for (cont = 0; cont < mycurve->step_count; cont++)
3162 		  steps =
3163 		    Motor_AddStep (steps, &bwriten, mycurve->step[cont]);
3164 	    }
3165 	}
3166     }
3167   else
3168     {
3169       /* acc.smearing curve disabled */
3170       data_wide_bitset (&Regs[0xfa], 0x3fff, 0);
3171     }
3172 
3173   /* dec.smearing */
3174   if (Motor_Curve_Get (dev, mysetting, DEC_CURVE, CRV_SMEARING) != NULL)
3175     {
3176       /* dec.smearing curve enabled */
3177       if (Motor_Curve_Equal
3178 	  (dev, mysetting, DEC_CURVE, CRV_SMEARING, CRV_BUFFERFULL) == TRUE)
3179 	{
3180 	  /* dec.smearing pointer points to dec.scanbufferfull table */
3181 	  data_wide_bitset (&Regs[0x00fc], 0x3fff,
3182 			    data_lsb_get (&Regs[0x00f8], 2));
3183 	  /* last step of dec.smearing table is the same as dec.scanbufferfull */
3184 	  data_lsb_set (&Regs[0x00f0], data_lsb_get (&Regs[0x00ea], 3), 3);
3185 	}
3186       else
3187 	{
3188 	  /* set pointer to next step table */
3189 	  if (mycurve != NULL)
3190 	    stepbuffer_size += (mycurve->step_count * 3);
3191 	  data_wide_bitset (&Regs[0xfc], 0x3fff, stepbuffer_size);
3192 
3193 	  /* set last step of dec.smearing table */
3194 	  mycurve = Motor_Curve_Get (dev, mysetting, DEC_CURVE, CRV_SMEARING);
3195 	  if (mycurve != NULL)
3196 	    {
3197 	      smeardeccurvecount = mycurve->step_count;
3198 	      data_lsb_set (&Regs[0xf0],
3199 			    mycurve->step[mycurve->step_count - 1], 3);
3200 
3201 	      /* generate dec.smearing table */
3202 	      if (mycurve->step_count > 0)
3203 		for (cont = 0; cont < mycurve->step_count; cont++)
3204 		  steps =
3205 		    Motor_AddStep (steps, &bwriten, mycurve->step[cont]);
3206 	    }
3207 	}
3208     }
3209   else
3210     {
3211       /* dec.smearing curve disabled */
3212       data_wide_bitset (&Regs[0x00fc], 0x3fff, 0);
3213     }
3214 
3215   /* dec.normalscan */
3216   if (Motor_Curve_Get (dev, mysetting, DEC_CURVE, CRV_NORMALSCAN) != NULL)
3217     {
3218       /* dec.normalscan enabled */
3219       if (Motor_Curve_Equal
3220 	  (dev, mysetting, DEC_CURVE, CRV_NORMALSCAN, CRV_BUFFERFULL) == TRUE)
3221 	{
3222 	  /* dec.normalscan pointer points to dec.scanbufferfull table */
3223 	  data_wide_bitset (&Regs[0xfe], 0x3fff,
3224 			    data_lsb_get (&Regs[0xf8], 2));
3225 	  /* last step of dec.normalscan table is the same as dec.scanbufferfull */
3226 	  data_lsb_set (&Regs[0xed], data_lsb_get (&Regs[0xea], 3), 3);
3227 	}
3228       else
3229 	if (Motor_Curve_Equal
3230 	    (dev, mysetting, DEC_CURVE, CRV_NORMALSCAN, CRV_SMEARING) == TRUE)
3231 	{
3232 	  /* dec.normalscan pointer points to dec.smearing table */
3233 	  data_wide_bitset (&Regs[0xfe], 0x3fff,
3234 			    data_lsb_get (&Regs[0xfc], 2));
3235 	  /* last step of dec.normalscan table is the same as dec.smearing */
3236 	  data_lsb_set (&Regs[0xed], data_lsb_get (&Regs[0xf0], 3), 3);
3237 	}
3238       else
3239 	{
3240 	  /* set pointer to next step table */
3241 	  if (mycurve != NULL)
3242 	    stepbuffer_size += (mycurve->step_count * 3);
3243 	  data_wide_bitset (&Regs[0xfe], 0x3fff, stepbuffer_size);
3244 
3245 	  /* set last step of dec.normalscan table */
3246 	  mycurve =
3247 	    Motor_Curve_Get (dev, mysetting, DEC_CURVE, CRV_NORMALSCAN);
3248 	  if (mycurve != NULL)
3249 	    {
3250 	      data_lsb_set (&Regs[0xed],
3251 			    mycurve->step[mycurve->step_count - 1], 3);
3252 
3253 	      /* generate dec.normalscan table */
3254 	      if (mycurve->step_count > 0)
3255 		for (cont = 0; cont < mycurve->step_count; cont++)
3256 		  steps =
3257 		    Motor_AddStep (steps, &bwriten, mycurve->step[cont]);
3258 	    }
3259 	}
3260     }
3261   else
3262     {
3263       /* dec.normalscan disabled */
3264       data_wide_bitset (&Regs[0xfe], 0x3fff, 0);
3265     }
3266 
3267   /* acc.parkhome */
3268   if (Motor_Curve_Get (dev, mysetting, ACC_CURVE, CRV_PARKHOME) != NULL)
3269     {
3270       /* parkhome curve enabled */
3271 
3272       if (Motor_Curve_Equal
3273 	  (dev, mysetting, ACC_CURVE, CRV_PARKHOME, CRV_NORMALSCAN) == TRUE)
3274 	{
3275 	  /* acc.parkhome pointer points to acc.normalscan table */
3276 	  data_wide_bitset (&Regs[0x100], 0x3fff,
3277 			    data_lsb_get (&Regs[0xf6], 2));
3278 
3279 	  /* last step of acc.parkhome table is the same as acc.normalscan */
3280 	  data_lsb_set (&Regs[0xe7], data_lsb_get (&Regs[0xe1], 3), 3);
3281 	}
3282       else
3283 	if (Motor_Curve_Equal
3284 	    (dev, mysetting, ACC_CURVE, CRV_PARKHOME, CRV_SMEARING) == TRUE)
3285 	{
3286 	  /* acc.parkhome pointer points to acc.smearing table */
3287 	  data_wide_bitset (&Regs[0x100], 0x3fff,
3288 			    data_lsb_get (&Regs[0xfa], 2));
3289 	  /* last step of acc.parkhome table is the same as acc.smearing */
3290 	  data_lsb_set (&Regs[0xe7], data_lsb_get (&Regs[0xe4], 3), 3);
3291 	}
3292       else
3293 	{
3294 	  /* set pointer to next step table */
3295 	  if (mycurve != NULL)
3296 	    stepbuffer_size += (mycurve->step_count * 3);
3297 	  data_wide_bitset (&Regs[0x100], 0x3fff, stepbuffer_size);
3298 
3299 	  /* set last step of acc.parkhome table */
3300 	  mycurve = Motor_Curve_Get (dev, mysetting, ACC_CURVE, CRV_PARKHOME);
3301 	  if (mycurve != NULL)
3302 	    {
3303 	      data_lsb_set (&Regs[0xe7],
3304 			    mycurve->step[mycurve->step_count - 1], 3);
3305 
3306 	      /* generate acc.parkhome table */
3307 	      if (mycurve->step_count > 0)
3308 		for (cont = 0; cont < mycurve->step_count; cont++)
3309 		  steps =
3310 		    Motor_AddStep (steps, &bwriten, mycurve->step[cont]);
3311 	    }
3312 	}
3313     }
3314   else
3315     {
3316       /* parkhome curve is disabled */
3317       /* acc.parkhome pointer points to 0 */
3318       data_wide_bitset (&Regs[0x100], 0x3fff, 0);
3319       data_lsb_set (&Regs[0xe7], 16, 3);
3320     }
3321 
3322   /* dec.parkhome */
3323   if (Motor_Curve_Get (dev, mysetting, DEC_CURVE, CRV_PARKHOME) != NULL)
3324     {
3325       /* parkhome curve enabled */
3326       if (Motor_Curve_Equal
3327 	  (dev, mysetting, DEC_CURVE, CRV_PARKHOME, CRV_BUFFERFULL) == TRUE)
3328 	{
3329 	  /* dec.parkhome pointer points to dec.scanbufferfull table */
3330 	  data_wide_bitset (&Regs[0x102], 0x3fff,
3331 			    data_lsb_get (&Regs[0xf8], 2));
3332 	  /* last step of dec.parkhome table is the same as dec.scanbufferfull */
3333 	  data_lsb_set (&Regs[0xf3], data_lsb_get (&Regs[0xe4], 3), 3);
3334 	}
3335       else
3336 	if (Motor_Curve_Equal
3337 	    (dev, mysetting, DEC_CURVE, CRV_PARKHOME, CRV_SMEARING) == TRUE)
3338 	{
3339 	  /* dec.parkhome pointer points to dec.smearing table */
3340 	  data_wide_bitset (&Regs[0x102], 0x3fff,
3341 			    data_lsb_get (&Regs[0xfe], 2));
3342 	  /* last step of dec.parkhome table is the same as dec.smearing */
3343 	  data_lsb_set (&Regs[0xf3], data_lsb_get (&Regs[0xf0], 3), 3);
3344 	}
3345       else
3346 	if (Motor_Curve_Equal
3347 	    (dev, mysetting, DEC_CURVE, CRV_PARKHOME, CRV_NORMALSCAN) == TRUE)
3348 	{
3349 	  /* dec.parkhome pointer points to dec.normalscan table */
3350 	  data_wide_bitset (&Regs[0x102], 0x3fff,
3351 			    data_lsb_get (&Regs[0xfe], 2));
3352 	  /* last step of dec.parkhome table is the same as dec.normalscan */
3353 	  data_lsb_set (&Regs[0xf3], data_lsb_get (&Regs[0xed], 3), 3);
3354 	}
3355       else
3356 	{
3357 	  /* set pointer to next step table */
3358 	  if (mycurve != NULL)
3359 	    stepbuffer_size += (mycurve->step_count * 3);
3360 	  data_wide_bitset (&Regs[0x102], 0x3fff, stepbuffer_size);
3361 
3362 	  /* set last step of dec.parkhome table */
3363 	  mycurve = Motor_Curve_Get (dev, mysetting, DEC_CURVE, CRV_PARKHOME);
3364 	  if (mycurve != NULL)
3365 	    {
3366 	      data_lsb_set (&Regs[0xf3],
3367 			    mycurve->step[mycurve->step_count - 1], 3);
3368 
3369 	      /* generate dec.parkhome table */
3370 	      if (mycurve->step_count > 0)
3371 		for (cont = 0; cont < mycurve->step_count; cont++)
3372 		  steps =
3373 		    Motor_AddStep (steps, &bwriten, mycurve->step[cont]);
3374 	    }
3375 	}
3376     }
3377   else
3378     {
3379       /* parkhome curve is disabled */
3380 
3381       /* dec.parkhome pointer points to 0 */
3382       data_wide_bitset (&Regs[0x102], 0x3fff, 0);
3383       data_lsb_set (&Regs[0xf3], 16, 3);
3384     }
3385 
3386   mybwriten = bwriten & 0x8000000f;
3387   if (mybwriten < 0)
3388     mybwriten = ((mybwriten - 1) | 0xfffffff0) + 1;
3389 
3390   if (mybwriten != 0)
3391     bwriten = (((bwriten & 0xffff) >> 0x04) + 1) << 0x04;
3392   bwriten = bwriten & 0xffff;
3393 
3394   /* display table */
3395   DBG (DBG_FNC, " -> Direction Type           Offset Last step\n");
3396   DBG (DBG_FNC, " -> --------- -------------- ------ ---------\n");
3397   DBG (DBG_FNC, " -> ACC_CURVE CRV_NORMALSCAN %6i  %6i\n",
3398        data_lsb_get (&Regs[0x0f6], 2) & 0x3fff, data_lsb_get (&Regs[0x0e1],
3399 							      3));
3400   DBG (DBG_FNC, " -> ACC_CURVE CRV_SMEARING   %6i  %6i\n",
3401        data_lsb_get (&Regs[0x0fa], 2) & 0x3fff, data_lsb_get (&Regs[0x0e4],
3402 							      3));
3403   DBG (DBG_FNC, " -> ACC_CURVE CRV_PARKHOME   %6i  %6i\n",
3404        data_lsb_get (&Regs[0x100], 2) & 0x3fff, data_lsb_get (&Regs[0x0e7],
3405 							      3));
3406   DBG (DBG_FNC, " -> DEC_CURVE CRV_NORMALSCAN %6i  %6i\n",
3407        data_lsb_get (&Regs[0x0fe], 2) & 0x3fff, data_lsb_get (&Regs[0x0ed],
3408 							      3));
3409   DBG (DBG_FNC, " -> DEC_CURVE CRV_SMEARING   %6i  %6i\n",
3410        data_lsb_get (&Regs[0x0fc], 2) & 0x3fff, data_lsb_get (&Regs[0x0f0],
3411 							      3));
3412   DBG (DBG_FNC, " -> DEC_CURVE CRV_PARKHOME   %6i  %6i\n",
3413        data_lsb_get (&Regs[0x102], 2) & 0x3fff, data_lsb_get (&Regs[0x0f3],
3414 							      3));
3415   DBG (DBG_FNC, " -> DEC_CURVE CRV_BUFFERFULL %6i  %6i\n",
3416        data_lsb_get (&Regs[0x0f8], 2) & 0x3fff, data_lsb_get (&Regs[0x0ea],
3417 							      3));
3418 
3419   RTS_Warm_Reset (dev);
3420 
3421   /* send motor steps */
3422   if (steps != NULL)
3423     {
3424       if (bwriten > 0)
3425 	{
3426 	  /* lock */
3427 	  SetLock (dev->usb_handle, Regs, TRUE);
3428 
3429 	  /* send steps */
3430 	  RTS_DMA_Write (dev, 0x0000, v15f8, bwriten, steps);
3431 
3432 	  /* unlock */
3433 	  SetLock (dev->usb_handle, Regs, FALSE);
3434 	}
3435 
3436       free (steps);
3437     }
3438 
3439   DBG (DBG_FNC, "- Motor_Setup_Steps: %i\n", acccurvecount);
3440 
3441   return acccurvecount;
3442 }
3443 
3444 static SANE_Int
Lamp_PWM_use(struct st_device * dev,SANE_Int enable)3445 Lamp_PWM_use (struct st_device *dev, SANE_Int enable)
3446 {
3447   SANE_Byte a, b;
3448   SANE_Int rst = ERROR;
3449 
3450   DBG (DBG_FNC, "+ Lamp_PWM_use(enable=%i):\n", enable);
3451 
3452   if (Read_Byte (dev->usb_handle, 0xe948, &a) == OK)
3453     {
3454       if (Read_Byte (dev->usb_handle, 0xe9e0, &b) == OK)
3455 	{
3456 	  if (enable != 0)
3457 	    {
3458 	      if (pwmlamplevel != 0x00)
3459 		{
3460 		  b |= 0x80;
3461 		  dev->init_regs[0x01e0] &= 0x3f;
3462 		  dev->init_regs[0x01e0] |= 0x80;
3463 		}
3464 	      else
3465 		{
3466 		  a |= 0x40;
3467 		  b &= 0x3f;
3468 		  dev->init_regs[0x0148] |= 0x40;
3469 		  dev->init_regs[0x01e0] &= 0x3f;
3470 		}
3471 	    }
3472 	  else
3473 	    {
3474 	      b &= 0x7f;
3475 	      a &= 0xbf;
3476 	    }
3477 
3478 	  if (Write_Byte (dev->usb_handle, 0xe948, a) == OK)
3479 	    rst = Write_Byte (dev->usb_handle, 0xe9e0, b);
3480 	}
3481     }
3482 
3483   DBG (DBG_FNC, "- Lamp_PWM_use: %i\n", rst);
3484 
3485   return rst;
3486 }
3487 
3488 static SANE_Int
SSCG_Enable(struct st_device * dev)3489 SSCG_Enable (struct st_device *dev)
3490 {
3491   SANE_Int rst;
3492   SANE_Int sscg;
3493   SANE_Byte data1, data2;
3494   SANE_Int enable, mode, clock;
3495 
3496   DBG (DBG_FNC, "+ SSCG_Enable:\n");
3497 
3498   rst = cfg_sscg_get (&enable, &mode, &clock);
3499 
3500   if (rst == OK)
3501     {
3502       if ((Read_Byte (dev->usb_handle, 0xfe3a, &data1) == OK)
3503 	  && (Read_Byte (dev->usb_handle, 0xfe39, &data2) == OK))
3504 	{
3505 	  if (enable != FALSE)
3506 	    {
3507 	      /* clock values: 0=0.25%; 1=0.50%; 2=0.75%; 3=1.00% */
3508 	      data2 = (mode == 0) ? data2 & 0x7f : data2 | 0x80;
3509 
3510 	      sscg = (data1 & 0xf3) | (((clock & 0x03) | 0x04) << 0x02);
3511 	      sscg = (sscg << 8) | data2;
3512 	    }
3513 	  else
3514 	    sscg = ((data1 & 0xef) << 8) | _B0 (data2);
3515 
3516 	  rst = Write_Word (dev->usb_handle, 0xfe39, sscg);
3517 	}
3518       else
3519 	rst = ERROR;
3520     }
3521 
3522   DBG (DBG_FNC, "- SSCG_Enable: %i\n", rst);
3523 
3524   return rst;
3525 }
3526 
3527 static void
RTS_Setup_RefVoltages(struct st_device * dev,SANE_Byte * Regs)3528 RTS_Setup_RefVoltages (struct st_device *dev, SANE_Byte * Regs)
3529 {
3530   /* this function sets top, midle and bottom reference voltages */
3531 
3532   DBG (DBG_FNC, "> RTS_Setup_RefVoltages\n");
3533 
3534   if (Regs != NULL)
3535     {
3536       SANE_Byte vrts, vrms, vrbs;
3537 
3538       cfg_refvoltages_get (dev->sensorcfg->type, &vrts, &vrms, &vrbs);
3539 
3540       /* Top Reference Voltage */
3541       data_bitset (&Regs[0x14], 0xe0, vrts);	/*xxx----- */
3542 
3543       /* Middle Reference Voltage */
3544       data_bitset (&Regs[0x15], 0xe0, vrms);	/*xxx----- */
3545 
3546       /* Bottom Reference Voltage */
3547       data_bitset (&Regs[0x16], 0xe0, vrbs);	/*xxx----- */
3548     }
3549 }
3550 
3551 static SANE_Int
Init_USBData(struct st_device * dev)3552 Init_USBData (struct st_device *dev)
3553 {
3554   SANE_Byte data;
3555   SANE_Byte *resource;
3556 
3557   DBG (DBG_FNC, "+ Init_USBData:\n");
3558 
3559   if (Read_Byte (dev->usb_handle, 0xf8ff, &data) != OK)
3560     return ERROR;
3561 
3562   data = (data | 1);
3563   if (Write_Byte (dev->usb_handle, 0xf8ff, data) != OK)
3564     return ERROR;
3565 
3566   if (SSCG_Enable (dev) != OK)
3567     return ERROR;
3568 
3569   Init_Registers (dev);
3570 
3571   /* Gamma table size = 0x100 */
3572   data_bitset (&dev->init_regs[0x1d0], 0x30, 0x00);	 /*--00----*/
3573 
3574   /* Set 3 channels_per_dot */
3575   data_bitset (&dev->init_regs[0x12], 0xc0, 0x03);	/*xx------ */
3576 
3577   /* systemclock */
3578   data_bitset (&dev->init_regs[0x00], 0x0f, 0x05);	 /*----xxxx*/
3579 
3580   /* timing cnpp */
3581   data_bitset (&dev->init_regs[0x96], 0x3f, 0x17);	 /*--xxxxxx*/
3582 
3583   /* set sensor_channel_color_order */
3584   data_bitset (&dev->init_regs[0x60a], 0x7f, 0x24);	 /*-xxxxxxx*/
3585 
3586   /* set crvs */
3587   data_bitset (&dev->init_regs[0x10], 0x1f, get_value (SCAN_PARAM, CRVS, 7, usbfile));	   /*---xxxxx*/
3588 
3589   /* set reference voltages */
3590   RTS_Setup_RefVoltages (dev, dev->init_regs);
3591 
3592   dev->init_regs[0x11] |= 0x10;
3593 
3594   data_bitset (&dev->init_regs[0x26], 0x70, 5);	     /*-101----*/
3595 
3596   dev->init_regs[0x185] = 0x88;
3597   dev->init_regs[0x186] = 0x88;
3598 
3599   /* SDRAM clock */
3600   data = get_value (SCAN_PARAM, MCLKIOC, 8, usbfile);
3601   data_bitset (&dev->init_regs[0x187], 0x0f, 0x08);	 /*----xxxx*/
3602   data_bitset (&dev->init_regs[0x187], 0xf0, data);	/*xxxx---- */
3603 
3604   data--;
3605 
3606   if (data < 7)
3607     {
3608       switch (data)
3609 	{
3610 	case 0:
3611 	  data |= 0xc0;
3612 	  break;
3613 	case 1:
3614 	  data |= 0xa0;
3615 	  break;
3616 	case 2:
3617 	  data |= 0xe0;
3618 	  break;
3619 	case 3:
3620 	  data |= 0x90;
3621 	  break;
3622 	case 4:
3623 	  data |= 0xd0;
3624 	  break;
3625 	case 5:
3626 	  data |= 0xb0;
3627 	  break;
3628 	case 6:
3629 	  data = (data & 0x0f);
3630 	  break;
3631 	}
3632       dev->init_regs[0x187] = _B0 (data);
3633     }
3634 
3635   data_bitset (&dev->init_regs[0x26], 0x0f, 0);	     /*----0000*/
3636 
3637   dev->init_regs[0x27] &= 0x3f;
3638   dev->init_regs[0x29] = 0x24;
3639   dev->init_regs[0x2a] = 0x10;
3640   dev->init_regs[0x150] = 0xff;
3641   dev->init_regs[0x151] = 0x13;
3642   dev->init_regs[0x156] = 0xf0;
3643   dev->init_regs[0x157] = 0xfd;
3644 
3645   if (dev->motorcfg->changemotorcurrent != FALSE)
3646     Motor_Change (dev, dev->init_regs, 3);
3647 
3648   dev->init_regs[0xde] = 0;
3649   data_bitset (&dev->init_regs[0xdf], 0x0f, 0);
3650 
3651   /* loads motor resource for this dev */
3652   resource = cfg_motor_resource_get (&data);
3653   if ((resource != NULL) && (data > 1))
3654     memcpy (&dev->init_regs[0x104], resource, data);
3655 
3656   /* this bit is set but I don't know its purpose */
3657   dev->init_regs[0x01] |= 0x40;	      /*-1------*/
3658 
3659   dev->init_regs[0x124] = 0x94;
3660 
3661   /* release motor */
3662   Motor_Release (dev);
3663 
3664   DBG (DBG_FNC, "- Init_USBData:\n");
3665 
3666   return OK;
3667 }
3668 
3669 static SANE_Int
Init_Registers(struct st_device * dev)3670 Init_Registers (struct st_device *dev)
3671 {
3672   SANE_Int rst = OK;
3673 
3674   DBG (DBG_FNC, "+ Init_Registers:\n");
3675 
3676   /* Lee dev->init_regs */
3677   memset (dev->init_regs, 0, RT_BUFFER_LEN);
3678   RTS_ReadRegs (dev->usb_handle, dev->init_regs);
3679   Read_FE3E (dev, &v1619);
3680 
3681   if (dev->sensorcfg->type == CCD_SENSOR)
3682     {
3683       /* CCD sensor */
3684       data_bitset (&dev->init_regs[0x11], 0xc0, 0);	/*xx------ */
3685       data_bitset (&dev->init_regs[0x146], 0x80, 1);	/*x------- */
3686       data_bitset (&dev->init_regs[0x146], 0x40, 1);		/*-x------*/
3687 
3688     }
3689   else
3690     {
3691       /* CIS sensor */
3692       data_bitset (&dev->init_regs[0x146], 0x80, 0);	/*0------- */
3693       data_bitset (&dev->init_regs[0x146], 0x40, 0);		/*-0------*/
3694       data_bitset (&dev->init_regs[0x11], 0xc0, 2);	/*xx------ */
3695       data_bitset (&dev->init_regs[0xae], 0x3f, 0x14);		/*--xxxxxx*/
3696       data_bitset (&dev->init_regs[0xaf], 0x07, 1);		/*-----xxx*/
3697 
3698       dev->init_regs[0x9c] = dev->init_regs[0xa2] = dev->init_regs[0xa8] =
3699 	(RTS_Debug->dev_model != UA4900) ? 1 : 0;
3700       dev->init_regs[0x9d] = dev->init_regs[0xa3] = dev->init_regs[0xa9] = 0;
3701       dev->init_regs[0x9e] = dev->init_regs[0xa4] = dev->init_regs[0xaa] = 0;
3702       dev->init_regs[0x9f] = dev->init_regs[0xa5] = dev->init_regs[0xab] = 0;
3703       dev->init_regs[0xa0] = dev->init_regs[0xa6] = dev->init_regs[0xac] = 0;
3704       dev->init_regs[0xa1] = dev->init_regs[0xa7] = dev->init_regs[0xad] =
3705 	(RTS_Debug->dev_model != UA4900) ? 0x80 : 0;
3706     }
3707 
3708   /* disable CCD channels */
3709   data_bitset (&dev->init_regs[0x10], 0xe0, 0);	/*xxx----- */
3710   data_bitset (&dev->init_regs[0x13], 0x80, 0);	/*x------- */
3711 
3712   /* enable timer to switch off lamp */
3713   data_bitset (&dev->init_regs[0x146], 0x10, 1);	 /*---x----*/
3714 
3715   /* set time to switch off lamp */
3716   dev->init_regs[0x147] = 0xff;
3717 
3718   /* set last acccurve step */
3719   data_lsb_set (&dev->init_regs[0xe1], 0x2af8, 3);
3720 
3721   /* set msi 0x02 */
3722   dev->init_regs[0xda] = 0x02;
3723   data_bitset (&dev->init_regs[0xdd], 0x03, 0);		/*------xx*/
3724 
3725   /* set binary threshold high and low in little endian */
3726   data_lsb_set (&dev->init_regs[0x19e], binarythresholdl, 2);
3727   data_lsb_set (&dev->init_regs[0x1a0], binarythresholdh, 2);
3728 
3729 
3730   data_bitset (&dev->init_regs[0x01], 0x08, 0);		/*----x---*/
3731   data_bitset (&dev->init_regs[0x16f], 0x40, 0);	/*-x------*/
3732   dev->init_regs[0x0bf] = (dev->init_regs[0x00bf] & 0xe0) | 0x20;
3733   dev->init_regs[0x163] = (dev->init_regs[0x0163] & 0x3f) | 0x40;
3734 
3735   data_bitset (&dev->init_regs[0xd6], 0x0f, 8);		/*----xxxx*/
3736   data_bitset (&dev->init_regs[0x164], 0x80, 1);	/*x------- */
3737 
3738   dev->init_regs[0x0bc] = 0x00;
3739   dev->init_regs[0x0bd] = 0x00;
3740 
3741   dev->init_regs[0x165] = (dev->init_regs[0x0165] & 0x3f) | 0x80;
3742   dev->init_regs[0x0ed] = 0x10;
3743   dev->init_regs[0x0be] = 0x00;
3744   dev->init_regs[0x0d5] = 0x00;
3745 
3746   dev->init_regs[0xee] = 0x00;
3747   dev->init_regs[0xef] = 0x00;
3748   dev->init_regs[0xde] = 0xff;
3749 
3750   /* set bit[4] has_curves = 0 | bit[0..3] unknown = 0 */
3751   data_bitset (&dev->init_regs[0xdf], 0x10, 0);		/*---x----*/
3752   data_bitset (&dev->init_regs[0xdf], 0x0f, 0);		/*----xxxx*/
3753 
3754   /* Set motor type */
3755   data_bitset (&dev->init_regs[0xd7], 0x80, dev->motorcfg->type);	/*x------- */
3756 
3757   if (dev->motorcfg->type == MT_ONCHIP_PWM)
3758     {
3759       data_bitset (&dev->init_regs[0x14e], 0x10, 1);	      /*---x----*/
3760 
3761       /* set motorpwmfrequency */
3762       data_bitset (&dev->init_regs[0xd7], 0x3f, dev->motorcfg->pwmfrequency);	       /*--xxxxxx*/
3763     }
3764 
3765   dev->init_regs[0x600] &= 0xfb;
3766   dev->init_regs[0x1d8] |= 0x08;
3767 
3768   v160c_block_size = 0x04;
3769   mem_total = 0x80000;
3770 
3771   /* check and setup installed ram */
3772   RTS_DMA_CheckType (dev, dev->init_regs);
3773   rst = RTS_DMA_WaitReady (dev, 1500);
3774 
3775   DBG (DBG_FNC, "- Init_Registers: %i\n", rst);
3776 
3777   return rst;
3778 }
3779 
3780 static SANE_Int
Read_FE3E(struct st_device * dev,SANE_Byte * destino)3781 Read_FE3E (struct st_device *dev, SANE_Byte * destino)
3782 {
3783   SANE_Int rst;
3784 
3785   DBG (DBG_FNC, "+ Read_FE3E:\n");
3786 
3787   rst = ERROR;
3788   if (destino != NULL)
3789     {
3790       SANE_Byte data;
3791       if (Read_Byte (dev->usb_handle, 0xfe3e, &data) == 0)
3792 	{
3793 	  *destino = data;
3794 	  rst = OK;
3795 	  DBG (DBG_FNC, " -> %02x\n", _B0 (data));
3796 	}
3797     }
3798 
3799   DBG (DBG_FNC, "- Read_FE3E: %i\n", rst);
3800 
3801   return rst;
3802 }
3803 
3804 static SANE_Int
Head_IsAtHome(struct st_device * dev,SANE_Byte * Regs)3805 Head_IsAtHome (struct st_device *dev, SANE_Byte * Regs)
3806 {
3807   SANE_Int rst;
3808 
3809   DBG (DBG_FNC, "+ Head_IsAtHome:\n");
3810 
3811   /* if returns TRUE, lamp is at home. Otherwise it returns FALSE */
3812   rst = 0;
3813 
3814   if (Regs != NULL)
3815     {
3816       SANE_Byte data;
3817       if (Read_Byte (dev->usb_handle, 0xe96f, &data) == OK)
3818 	{
3819 	  Regs[0x16f] = _B0 (data);
3820 	  rst = (data >> 6) & 1;
3821 	}
3822     }
3823 
3824   rst = (rst == 1) ? TRUE : FALSE;
3825 
3826   DBG (DBG_FNC, "- Head_IsAtHome: %s\n", (rst == TRUE) ? "Yes" : "No");
3827 
3828   return rst;
3829 }
3830 
3831 static SANE_Byte
RTS_IsExecuting(struct st_device * dev,SANE_Byte * Regs)3832 RTS_IsExecuting (struct st_device *dev, SANE_Byte * Regs)
3833 {
3834   SANE_Byte rst;
3835 
3836   DBG (DBG_FNC, "+ RTS_IsExecuting:\n");
3837 
3838   rst = 0;
3839 
3840   if (Regs != NULL)
3841     {
3842       SANE_Byte data;
3843       if (Read_Byte (dev->usb_handle, 0xe800, &data) == OK)
3844 	{
3845 	  Regs[0x00] = data;
3846 	  rst = (data >> 7) & 1;
3847 	}
3848     }
3849 
3850   DBG (DBG_FNC, "- RTS_IsExecuting: %i\n", rst);
3851 
3852   return rst;
3853 }
3854 
3855 static SANE_Int
RTS_WaitScanEnd(struct st_device * dev,SANE_Int msecs)3856 RTS_WaitScanEnd (struct st_device *dev, SANE_Int msecs)
3857 {
3858   SANE_Byte data;
3859   SANE_Int rst;
3860 
3861   DBG (DBG_FNC, "+ RTS_WaitScanEnd(msecs=%i):\n", msecs);
3862 
3863   /* returns 0 if ok or timeout
3864      returns -1 if fails */
3865 
3866   rst = ERROR;
3867 
3868   if (Read_Byte (dev->usb_handle, 0xe800, &data) == OK)
3869     {
3870       long ticks = GetTickCount () + msecs;
3871       rst = OK;
3872       while (((data & 0x80) != 0) && (ticks > GetTickCount ()) && (rst == OK))
3873 	{
3874 	  rst = Read_Byte (dev->usb_handle, 0xe800, &data);
3875 	}
3876     }
3877 
3878   DBG (DBG_FNC, "- RTS_WaitScanEnd: Ending with rst=%i\n", rst);
3879 
3880   return rst;
3881 }
3882 
3883 static SANE_Int
RTS_Enable_CCD(struct st_device * dev,SANE_Byte * Regs,SANE_Int channels)3884 RTS_Enable_CCD (struct st_device *dev, SANE_Byte * Regs, SANE_Int channels)
3885 {
3886   SANE_Int rst = ERROR;
3887 
3888   DBG (DBG_FNC, "+ RTS_Enable_CCD(*Regs, arg2=%i):\n", channels);
3889 
3890   if (Read_Buffer (dev->usb_handle, 0xe810, &Regs[0x10], 4) == OK)
3891     {
3892       data_bitset (&Regs[0x10], 0xe0, channels);	/*xxx----- */
3893       data_bitset (&Regs[0x13], 0x80, channels >> 3);	/*x------- */
3894 
3895       Write_Buffer (dev->usb_handle, 0xe810, &Regs[0x10], 4);
3896       rst = OK;
3897     }
3898 
3899   DBG (DBG_FNC, "- RTS_Enable_CCD: %i\n", rst);
3900 
3901   return rst;
3902 }
3903 
3904 static SANE_Int
RTS_Warm_Reset(struct st_device * dev)3905 RTS_Warm_Reset (struct st_device *dev)
3906 {
3907   SANE_Byte data;
3908   SANE_Int rst;
3909 
3910   DBG (DBG_FNC, "+ RTS_Warm_Reset:\n");
3911 
3912   rst = ERROR;
3913   if (Read_Byte (dev->usb_handle, 0xe800, &data) == OK)
3914     {
3915       data = (data & 0x3f) | 0x40;	/*01------ */
3916       if (Write_Byte (dev->usb_handle, 0xe800, data) == OK)
3917 	{
3918 	  data &= 0xbf;		      /*-0------*/
3919 	  rst = Write_Byte (dev->usb_handle, 0xe800, data);
3920 	}
3921     }
3922 
3923   DBG (DBG_FNC, "- RTS_Warm_Reset: %i\n", rst);
3924 
3925   return rst;
3926 }
3927 
3928 static SANE_Int
Lamp_Status_Timer_Set(struct st_device * dev,SANE_Int minutes)3929 Lamp_Status_Timer_Set (struct st_device *dev, SANE_Int minutes)
3930 {
3931   SANE_Byte MyBuffer[2];
3932   SANE_Int rst;
3933 
3934   DBG (DBG_FNC, "+ Lamp_Status_Timer_Set(minutes=%i):\n", minutes);
3935 
3936   MyBuffer[0] = dev->init_regs[0x0146] & 0xef;
3937   MyBuffer[1] = dev->init_regs[0x0147];
3938 
3939   if (minutes > 0)
3940     {
3941       double rst, op2;
3942 
3943       minutes = _B0 (minutes);
3944       op2 = 2.682163611980331;
3945       MyBuffer[0x00] |= 0x10;
3946       rst = (minutes * op2);
3947       MyBuffer[0x01] = (SANE_Byte) floor (rst);
3948     }
3949 
3950   dev->init_regs[0x147] = MyBuffer[1];
3951   dev->init_regs[0x146] =
3952     (dev->init_regs[0x146] & 0xef) | (MyBuffer[0] & 0x10);
3953 
3954   rst =
3955     Write_Word (dev->usb_handle, 0xe946,
3956 		(SANE_Int) ((MyBuffer[1] << 8) + MyBuffer[0]));
3957 
3958   DBG (DBG_FNC, "- Lamp_Status_Timer_Set: %i\n", rst);
3959 
3960   return rst;
3961 }
3962 
3963 static SANE_Int
Buttons_Enable(struct st_device * dev)3964 Buttons_Enable (struct st_device *dev)
3965 {
3966   SANE_Int data, rst;
3967 
3968   DBG (DBG_FNC, "+ Buttons_Enable:\n");
3969 
3970   if (Read_Word (dev->usb_handle, 0xe958, &data) == OK)
3971     {
3972       data |= 0x0f;
3973       rst = Write_Word (dev->usb_handle, 0xe958, data);
3974     }
3975   else
3976     rst = ERROR;
3977 
3978   DBG (DBG_FNC, "- Buttons_Enable: %i\n", rst);
3979 
3980   return rst;
3981 }
3982 
3983 static SANE_Int
Buttons_Count(struct st_device * dev)3984 Buttons_Count (struct st_device *dev)
3985 {
3986   SANE_Int rst = 0;
3987 
3988   /* This chipset supports up to six buttons */
3989 
3990   if (dev->buttons != NULL)
3991     rst = dev->buttons->count;
3992 
3993   DBG (DBG_FNC, "> Buttons_Count: %i\n", rst);
3994 
3995   return rst;
3996 }
3997 
3998 static SANE_Int
Buttons_Status(struct st_device * dev)3999 Buttons_Status (struct st_device *dev)
4000 {
4001   SANE_Int rst = -1;
4002   SANE_Byte data;
4003 
4004   DBG (DBG_FNC, "+ Buttons_Status\n");
4005 
4006   /* Each bit is 1 if button is not pressed, and 0 if it is pressed
4007      This chipset supports up to six buttons */
4008 
4009   if (Read_Byte (dev->usb_handle, 0xe968, &data) == OK)
4010     rst = _B0 (data);
4011 
4012   DBG (DBG_FNC, "- Buttons_Status: %i\n", rst);
4013 
4014   return rst;
4015 }
4016 
4017 static SANE_Int
Buttons_Released(struct st_device * dev)4018 Buttons_Released (struct st_device *dev)
4019 {
4020   SANE_Int rst = -1;
4021   SANE_Byte data;
4022 
4023   DBG (DBG_FNC, "+ Buttons_Released\n");
4024 
4025   /* Each bit is 1 if button is released, until reading this register. Then
4026      entire register is cleared. This chipset supports up to six buttons */
4027 
4028   if (Read_Byte (dev->usb_handle, 0xe96a, &data) == OK)
4029     rst = _B0 (data);
4030 
4031   DBG (DBG_FNC, "- Buttons_Released: %i\n", rst);
4032 
4033   return rst;
4034 }
4035 
4036 static SANE_Int
Buttons_Order(struct st_device * dev,SANE_Int mask)4037 Buttons_Order (struct st_device *dev, SANE_Int mask)
4038 {
4039   /* this is a way to order each button according to its bit in register 0xe968 */
4040   SANE_Int rst = -1;
4041 
4042   if (dev->buttons != NULL)
4043     {
4044       SANE_Int a;
4045 
4046       for (a = 0; a < 6; a++)
4047 	{
4048 	  if (dev->buttons->mask[a] == mask)
4049 	    {
4050 	      rst = a;
4051 	      break;
4052 	    }
4053 	}
4054     }
4055 
4056   return rst;
4057 }
4058 
4059 static SANE_Int
GainOffset_Clear(struct st_device * dev)4060 GainOffset_Clear (struct st_device *dev)
4061 {
4062   SANE_Int rst = OK;
4063 
4064   DBG (DBG_FNC, "+ GainOffset_Clear:\n");
4065 
4066   /* clear offsets */
4067   offset[CL_RED] = offset[CL_GREEN] = offset[CL_BLUE] = 0;
4068 
4069   /* save offsets */
4070   /* check if chipset supports accessing eeprom */
4071   if ((dev->chipset->capabilities & CAP_EEPROM) != 0)
4072     {
4073       SANE_Int a;
4074 
4075       for (a = CL_RED; a <= CL_BLUE; a++)
4076 	RTS_EEPROM_WriteWord (dev->usb_handle, 0x70 + (2 * a), 0);
4077 
4078       /* update checksum */
4079       rst = RTS_EEPROM_WriteByte (dev->usb_handle, 0x76, 0);
4080     }
4081 
4082   DBG (DBG_FNC, "- GainOffset_Clear: %i\n", rst);
4083 
4084   return rst;
4085 }
4086 
4087 static SANE_Int
Lamp_Status_Get(struct st_device * dev,SANE_Byte * flb_lamp,SANE_Byte * tma_lamp)4088 Lamp_Status_Get (struct st_device *dev, SANE_Byte * flb_lamp,
4089 		 SANE_Byte * tma_lamp)
4090 {
4091   /* The only reason that I think windows driver uses two variables to get
4092      which lamp is switched on instead of one variable is that some chipset
4093      model could have both lamps switched on, so I'm maintaining such var */
4094 
4095   SANE_Int rst = ERROR;		/* default */
4096 
4097   DBG (DBG_FNC, "+ Lamp_Status_Get:\n");
4098 
4099   if ((flb_lamp != NULL) && (tma_lamp != NULL))
4100     {
4101       SANE_Int data1;
4102       SANE_Byte data2;
4103 
4104       if (Read_Byte (dev->usb_handle, 0xe946, &data2) == OK)
4105 	{
4106 	  if (Read_Word (dev->usb_handle, 0xe954, &data1) == OK)
4107 	    {
4108 	      rst = OK;
4109 
4110 	      *flb_lamp = 0;
4111 	      *tma_lamp = 0;
4112 
4113 	      switch (dev->chipset->model)
4114 		{
4115 		case RTS8822BL_03A:
4116 		  *flb_lamp = ((data2 & 0x40) != 0) ? 1 : 0;
4117 		  *tma_lamp = (((data2 & 0x20) != 0)
4118 			       && ((data1 & 0x10) != 0)) ? 1 : 0;
4119 		  break;
4120 		default:
4121 		  if ((_B1 (data1) & 0x10) == 0)
4122 		    *flb_lamp = (data2 >> 6) & 1;
4123 		  else
4124 		    *tma_lamp = (data2 >> 6) & 1;
4125 		  break;
4126 		}
4127 	    }
4128 	}
4129     }
4130 
4131   DBG (DBG_FNC, "- Lamp_Status_Get: rst=%i flb=%i tma=%i\n", rst,
4132        _B0 (*flb_lamp), _B0 (*tma_lamp));
4133 
4134   return rst;
4135 }
4136 
4137 static SANE_Int
RTS_DMA_WaitReady(struct st_device * dev,SANE_Int msecs)4138 RTS_DMA_WaitReady (struct st_device *dev, SANE_Int msecs)
4139 {
4140   SANE_Byte data;
4141   SANE_Int rst;
4142   long mytime;
4143 
4144   DBG (DBG_FNC, "+ RTS_DMA_WaitReady(msecs=%i):\n", msecs);
4145 
4146   rst = OK;
4147   mytime = GetTickCount () + msecs;
4148 
4149   while ((mytime > GetTickCount ()) && (rst == OK))
4150     {
4151       if (Read_Byte (dev->usb_handle, 0xef09, &data) == OK)
4152 	{
4153 	  if ((data & 1) == 0)
4154 	    usleep (1000 * 100);
4155 	  else
4156 	    break;
4157 	}
4158       else
4159 	rst = ERROR;
4160     }
4161 
4162   DBG (DBG_FNC, "- RTS_DMA_WaitReady: %i\n", rst);
4163 
4164   return rst;
4165 }
4166 
4167 static SANE_Int
RTS_WaitInitEnd(struct st_device * dev,SANE_Int msecs)4168 RTS_WaitInitEnd (struct st_device *dev, SANE_Int msecs)
4169 {
4170   SANE_Byte data;
4171   SANE_Int rst;
4172   long mytime;
4173 
4174   DBG (DBG_FNC, "+ RTS_WaitInitEnd(msecs=%i):\n", msecs);
4175 
4176   rst = OK;
4177   mytime = GetTickCount () + msecs;
4178 
4179   while ((mytime > GetTickCount ()) && (rst == OK))
4180     {
4181       if (Read_Byte (dev->usb_handle, 0xf910, &data) == OK)
4182 	{
4183 	  if ((data & 8) == 0)
4184 	    usleep (1000 * 100);
4185 	  else
4186 	    break;
4187 	}
4188       else
4189 	rst = ERROR;
4190     }
4191 
4192   DBG (DBG_FNC, "- RTS_WaitInitEnd: %i\n", rst);
4193 
4194   return rst;
4195 }
4196 
4197 static SANE_Int
Motor_Change(struct st_device * dev,SANE_Byte * buffer,SANE_Byte value)4198 Motor_Change (struct st_device *dev, SANE_Byte * buffer, SANE_Byte value)
4199 {
4200   SANE_Int data, rst;
4201 
4202   DBG (DBG_FNC, "+ Motor_Change(*buffer, value=%i):\n", value);
4203 
4204   if (Read_Word (dev->usb_handle, 0xe954, &data) == OK)
4205     {
4206       data &= 0xcf;	      /*--00----*/
4207       value--;
4208       switch (value)
4209 	{
4210 	case 2:
4211 	  data |= 0x30;
4212 	  break;				     /*--11----*/
4213 	case 1:
4214 	  data |= 0x20;
4215 	  break;				     /*--10----*/
4216 	case 0:
4217 	  data |= 0x10;
4218 	  break;				     /*--01----*/
4219 	}
4220 
4221       buffer[0x154] = _B0 (data);
4222 
4223       rst = Write_Byte (dev->usb_handle, 0xe954, buffer[0x154]);
4224     }
4225   else
4226     rst = ERROR;
4227 
4228   DBG (DBG_FNC, "- Motor_Change: %i\n", rst);
4229 
4230   return rst;
4231 }
4232 
4233 static SANE_Int
RTS_DMA_Read(struct st_device * dev,SANE_Int dmacs,SANE_Int options,SANE_Int size,SANE_Byte * buffer)4234 RTS_DMA_Read (struct st_device *dev, SANE_Int dmacs, SANE_Int options,
4235 	      SANE_Int size, SANE_Byte * buffer)
4236 {
4237   SANE_Int rst = ERROR;
4238 
4239   DBG (DBG_FNC,
4240        "+ RTS_DMA_Read(dmacs=%04x, options=%04x, size=%i., *buffer):\n",
4241        dmacs, options, size);
4242 
4243   /* is there any buffer to send? */
4244   if ((buffer != NULL) && (size > 0))
4245     {
4246       /* reset dma */
4247       if (RTS_DMA_Reset (dev) == OK)
4248 	{
4249 	  /* prepare dma to read */
4250 	  if (RTS_DMA_Enable_Read (dev, dmacs, size, options) == OK)
4251 	    {
4252 	      SANE_Int transferred;
4253 
4254 	      rst =
4255 		Bulk_Operation (dev, BLK_READ, size, buffer, &transferred);
4256 	    }
4257 	}
4258     }
4259 
4260   DBG (DBG_FNC, "- RTS_DMA_Read(): %i\n", rst);
4261 
4262   return rst;
4263 }
4264 
4265 static SANE_Int
RTS_DMA_Write(struct st_device * dev,SANE_Int dmacs,SANE_Int options,SANE_Int size,SANE_Byte * buffer)4266 RTS_DMA_Write (struct st_device *dev, SANE_Int dmacs, SANE_Int options,
4267 	       SANE_Int size, SANE_Byte * buffer)
4268 {
4269   SANE_Int rst = ERROR;
4270 
4271   DBG (DBG_FNC,
4272        "+ RTS_DMA_Write(dmacs=%04x, options=%04x, size=%i., *buffer):\n",
4273        dmacs, options, size);
4274 
4275   /* is there any buffer to send? */
4276   if ((buffer != NULL) && (size > 0))
4277     {
4278       /* reset dma */
4279       if (RTS_DMA_Reset (dev) == OK)
4280 	{
4281 	  /* prepare dma to write */
4282 	  if (RTS_DMA_Enable_Write (dev, dmacs, size, options) == OK)
4283 	    {
4284 	      SANE_Int transferred;
4285 	      SANE_Byte *check_buffer;
4286 
4287 	      check_buffer = (SANE_Byte *) malloc (size);
4288 	      if (check_buffer != NULL)
4289 		{
4290 		  /* if some transfer fails we try again until ten times */
4291 		  SANE_Int a;
4292 		  for (a = 10; a > 0; a--)
4293 		    {
4294 		      /* send buffer */
4295 		      Bulk_Operation (dev, BLK_WRITE, size, buffer,
4296 				      &transferred);
4297 
4298 		      /* prepare dma to read */
4299 		      if (RTS_DMA_Enable_Read (dev, dmacs, size, options) ==
4300 			  OK)
4301 			{
4302 			  SANE_Int b = 0, diff = FALSE;
4303 
4304 			  /* read buffer */
4305 			  Bulk_Operation (dev, BLK_READ, size, check_buffer,
4306 					  &transferred);
4307 
4308 			  /* check buffers */
4309 			  while ((b < size) && (diff == FALSE))
4310 			    {
4311 			      if (buffer[b] == check_buffer[b])
4312 				b++;
4313 			      else
4314 				diff = TRUE;
4315 			    }
4316 
4317 			  /* if buffers are equal we can break loop */
4318 			  if (diff == TRUE)
4319 			    {
4320 			      /* cancel dma */
4321 			      RTS_DMA_Cancel (dev);
4322 
4323 			      /* prepare dma to write buffer again */
4324 			      if (RTS_DMA_Enable_Write
4325 				  (dev, dmacs, size, options) != OK)
4326 				break;
4327 			    }
4328 			  else
4329 			    {
4330 			      /* everything went ok */
4331 			      rst = OK;
4332 			      break;
4333 			    }
4334 			}
4335 		      else
4336 			break;
4337 		    }
4338 
4339 		  /* free check buffer */
4340 		  free (check_buffer);
4341 		}
4342 	      else
4343 		{
4344 		  /* for some reason it's not possible to allocate space to check
4345 		     sent buffer so we just write data */
4346 		  Bulk_Operation (dev, BLK_WRITE, size, buffer, &transferred);
4347 		  rst = OK;
4348 		}
4349 	    }
4350 	}
4351     }
4352 
4353   DBG (DBG_FNC, "- RTS_DMA_Write(): %i\n", rst);
4354 
4355   return rst;
4356 }
4357 
4358 static SANE_Int
RTS_DMA_CheckType(struct st_device * dev,SANE_Byte * Regs)4359 RTS_DMA_CheckType (struct st_device *dev, SANE_Byte * Regs)
4360 {
4361   /* This function tries to detect what kind of RAM supports chipset */
4362   /* Returns a value between 0 and 4. -1 means error */
4363 
4364   SANE_Int rst = -1;
4365 
4366   DBG (DBG_FNC, "+ RTS_DMA_CheckType(*Regs):\n");
4367 
4368   if (Regs != NULL)
4369     {
4370       SANE_Byte *out_buffer;
4371 
4372       /* define buffer to send */
4373       out_buffer = (SANE_Byte *) malloc (sizeof (SANE_Byte) * 2072);
4374       if (out_buffer != NULL)
4375 	{
4376 	  SANE_Byte *in_buffer;
4377 
4378 	  /* define incoming buffer */
4379 	  in_buffer = (SANE_Byte *) malloc (sizeof (SANE_Byte) * 2072);
4380 	  if (in_buffer != NULL)
4381 	    {
4382 	      SANE_Int a, b, diff;
4383 
4384 	      /* fill outgoing buffer with a known pattern */
4385 	      b = 0;
4386 	      for (a = 0; a < 2072; a++)
4387 		{
4388 		  out_buffer[a] = b;
4389 		  b++;
4390 		  if (b == 0x61)
4391 		    b = 0;
4392 		}
4393 
4394 	      /* let's send buffer with different ram types and compare
4395 	         incoming buffer until getting the right type */
4396 
4397 	      for (a = 4; a >= 0; a--)
4398 		{
4399 		  /* set ram type */
4400 		  if (RTS_DMA_SetType (dev, Regs, a) != OK)
4401 		    break;
4402 
4403 		  /* wait 1500 milliseconds */
4404 		  if (RTS_DMA_WaitReady (dev, 1500) == OK)
4405 		    {
4406 		      /* reset dma */
4407 		      RTS_DMA_Reset (dev);
4408 
4409 		      /* write buffer */
4410 		      RTS_DMA_Write (dev, 0x0004, 0x102, 2072, out_buffer);
4411 
4412 		      /* now read buffer */
4413 		      RTS_DMA_Read (dev, 0x0004, 0x102, 2072, in_buffer);
4414 
4415 		      /* check buffers */
4416 		      b = 0;
4417 		      diff = FALSE;
4418 		      while ((b < 2072) && (diff == FALSE))
4419 			{
4420 			  if (out_buffer[b] == in_buffer[b])
4421 			    b++;
4422 			  else
4423 			    diff = TRUE;
4424 			}
4425 
4426 		      /* if buffers are equal */
4427 		      if (diff == FALSE)
4428 			{
4429 			  SANE_Int data = 0;
4430 
4431 			  /* buffers are equal so we've found the right ram type */
4432 			  memset (out_buffer, 0, 0x20);
4433 			  for (b = 0; b < 0x20; b += 2)
4434 			    out_buffer[b] = b;
4435 
4436 			  /* write buffer */
4437 			  if (RTS_DMA_Write
4438 			      (dev, 0x0004, 0x0000, 0x20, out_buffer) == OK)
4439 			    {
4440 			      SANE_Int c = 0;
4441 			      diff = TRUE;
4442 
4443 			      do
4444 				{
4445 				  c++;
4446 				  for (b = 1; b < 0x20; b += 2)
4447 				    out_buffer[b] = c;
4448 
4449 				  if (RTS_DMA_Write
4450 				      (dev, 0x0004, (_B0 (c) << 0x11) >> 0x04,
4451 				       0x20, out_buffer) == OK)
4452 				    {
4453 				      if (RTS_DMA_Read
4454 					  (dev, 0x0004, 0x0000, 0x20,
4455 					   in_buffer) == OK)
4456 					{
4457 					  b = 0;
4458 					  diff = FALSE;
4459 					  while ((b < 0x20)
4460 						 && (diff == FALSE))
4461 					    {
4462 					      if (out_buffer[b] ==
4463 						  in_buffer[b])
4464 						b++;
4465 					      else
4466 						diff = TRUE;
4467 					    }
4468 
4469 					  if (diff == FALSE)
4470 					    data = c << 7;
4471 					}
4472 				    }
4473 				}
4474 			      while ((c < 0x80) && (diff == TRUE));
4475 			    }
4476 
4477 			  switch (data)
4478 			    {
4479 			    case 16384:
4480 			      Regs[0x708] &= 0x1f;
4481 			      Regs[0x708] |= 0x80;
4482 			      break;
4483 			    case 8192:
4484 			      Regs[0x708] &= 0x1f;
4485 			      Regs[0x708] |= 0x60;
4486 			      break;
4487 			    case 4096:
4488 			      Regs[0x708] &= 0x1f;
4489 			      Regs[0x708] |= 0x40;
4490 			      break;
4491 			    case 2048:
4492 			      Regs[0x708] &= 0x1f;
4493 			      Regs[0x708] |= 0x20;
4494 			      break;
4495 			    case 1024:
4496 			      Regs[0x708] &= 0x1f;
4497 			      data = 0x200;
4498 			      break;
4499 			    case 128:
4500 			      Regs[0x708] &= 0x1f;
4501 			      break;
4502 			    }
4503 
4504 			  DBG (DBG_FNC, " -> data1 = 0x%08x\n",
4505 			       (data * 4) * 1024);
4506 			  DBG (DBG_FNC, " -> data2 = 0x%08x\n", data * 1024);
4507 			  DBG (DBG_FNC, " -> type  = 0x%04x\n",
4508 			       Regs[0x708] >> 5);
4509 
4510 			  RTS_DMA_SetType (dev, Regs, Regs[0x708] >> 5);
4511 
4512 			  rst = OK;
4513 			  break;
4514 			}
4515 		    }
4516 		  else
4517 		    break;
4518 		}
4519 
4520 	      free (in_buffer);
4521 	    }
4522 
4523 	  free (out_buffer);
4524 	}
4525     }
4526 
4527   DBG (DBG_FNC, "- RTS_DMA_CheckType(): %i\n", rst);
4528 
4529   return rst;
4530 }
4531 
4532 static SANE_Int
RTS_DMA_SetType(struct st_device * dev,SANE_Byte * Regs,SANE_Byte ramtype)4533 RTS_DMA_SetType (struct st_device *dev, SANE_Byte * Regs, SANE_Byte ramtype)
4534 {
4535   SANE_Int rst = ERROR;
4536 
4537   DBG (DBG_FNC, "+ RTS_DMA_SetType(*Regs, ramtype=%i):\n", ramtype);
4538 
4539   if (Regs != NULL)
4540     {
4541       data_bitset (&Regs[0x708], 0x08, 0);	    /*----0---*/
4542 
4543       if (Write_Byte (dev->usb_handle, 0xef08, Regs[0x708]) == OK)
4544 	{
4545 	  data_bitset (&Regs[0x708], 0xe0, ramtype);
4546 
4547 	  if (Write_Byte (dev->usb_handle, 0xef08, Regs[0x708]) == OK)
4548 	    {
4549 	      data_bitset (&Regs[0x708], 0x08, 1);		    /*----1---*/
4550 	      rst = Write_Byte (dev->usb_handle, 0xef08, Regs[0x708]);
4551 	    }
4552 	}
4553     }
4554 
4555   DBG (DBG_FNC, "- RTS_DMA_SetType: %i\n", rst);
4556 
4557   return rst;
4558 }
4559 
4560 static void
Motor_Release(struct st_device * dev)4561 Motor_Release (struct st_device *dev)
4562 {
4563   SANE_Byte data = 0;
4564 
4565   DBG (DBG_FNC, "+ Motor_Release:\n");
4566 
4567   if (Read_Byte (dev->usb_handle, 0xe8d9, &data) == OK)
4568     {
4569       data |= 4;
4570       Write_Byte (dev->usb_handle, 0xe8d9, data);
4571     }
4572 
4573   DBG (DBG_FNC, "- Motor_Release:\n");
4574 }
4575 
4576 static SANE_Byte
GainOffset_Counter_Load(struct st_device * dev)4577 GainOffset_Counter_Load (struct st_device *dev)
4578 {
4579   SANE_Byte data = 0x0f;
4580 
4581   DBG (DBG_FNC, "+ GainOffset_Counter_Load:\n");
4582 
4583   /* check if chipset supports accessing eeprom */
4584   if ((dev->chipset->capabilities & CAP_EEPROM) != 0)
4585     if (RTS_EEPROM_ReadByte (dev->usb_handle, 0x77, &data) != OK)
4586       data = 0x0f;
4587 
4588   DBG (DBG_FNC, "- GainOffset_Counter_Load: %i\n", _B0 (data));
4589 
4590   return data;
4591 }
4592 
4593 static SANE_Int
RTS_Execute(struct st_device * dev)4594 RTS_Execute (struct st_device *dev)
4595 {
4596   SANE_Byte e813, e800;
4597   SANE_Int ret;
4598 
4599   DBG (DBG_FNC, "+ RTS_Execute:\n");
4600 
4601   e813 = 0;
4602   e800 = 0;
4603   ret = ERROR;
4604 
4605   if (Read_Byte (dev->usb_handle, 0xe800, &e800) == OK)
4606     {
4607       if (Read_Byte (dev->usb_handle, 0xe813, &e813) == OK)
4608 	{
4609 	  e813 &= 0xbf;
4610 	  if (Write_Byte (dev->usb_handle, 0xe813, e813) == OK)
4611 	    {
4612 	      e800 |= 0x40;
4613 	      if (Write_Byte (dev->usb_handle, 0xe800, e800) == OK)
4614 		{
4615 		  e813 |= 0x40;
4616 		  if (Write_Byte (dev->usb_handle, 0xe813, e813) == OK)
4617 		    {
4618 		      e800 &= 0xbf;
4619 		      if (Write_Byte (dev->usb_handle, 0xe800, e800) == OK)
4620 			{
4621 			  usleep (1000 * 100);
4622 			  e800 |= 0x80;
4623 			  ret = Write_Byte (dev->usb_handle, 0xe800, e800);
4624 			}
4625 		    }
4626 		}
4627 	    }
4628 	}
4629     }
4630 
4631   DBG (DBG_FNC, "- RTS_Execute: %i\n", ret);
4632 
4633   return ret;
4634 }
4635 
4636 static SANE_Int
RTS_isTmaAttached(struct st_device * dev)4637 RTS_isTmaAttached (struct st_device *dev)
4638 {
4639   SANE_Int rst;
4640 
4641   DBG (DBG_FNC, "+ RTS_isTmaAttached:\n");
4642 
4643   /* returns 0 if Tma is attached. Otherwise 1 */
4644   if (Read_Word (dev->usb_handle, 0xe968, &rst) == OK)
4645     {
4646       rst = ((_B1 (rst) & 2) != 0) ? FALSE : TRUE;
4647     }
4648   else
4649     rst = TRUE;
4650 
4651   DBG (DBG_FNC, "- RTS_isTmaAttached: %s\n", (rst == TRUE) ? "Yes" : "No");
4652 
4653   return rst;
4654 }
4655 
4656 static SANE_Int
Gamma_AllocTable(SANE_Byte * table)4657 Gamma_AllocTable (SANE_Byte * table)
4658 {
4659   SANE_Int C;
4660   SANE_Int rst = OK;
4661 
4662   hp_gamma->depth = 8;
4663 
4664   for (C = 0; C < 3; C++)
4665     if (hp_gamma->table[C] == NULL)
4666       hp_gamma->table[C] = malloc (sizeof (SANE_Byte) * 256);
4667 
4668   if ((hp_gamma->table[CL_RED] != NULL) &&
4669       (hp_gamma->table[CL_GREEN] != NULL) &&
4670       (hp_gamma->table[CL_BLUE] != NULL))
4671     {
4672       /* All tables allocated */
4673       for (C = 0; C < 256; C++)
4674 	{
4675 	  if ((table != NULL) && (RTS_Debug->EnableGamma == TRUE))
4676 	    {
4677 	      /* fill gamma tables with user defined values */
4678 	      hp_gamma->table[CL_RED][C] = table[C];
4679 	      hp_gamma->table[CL_GREEN][C] = table[0x100 + C];
4680 	      hp_gamma->table[CL_BLUE][C] = table[0x200 + C];
4681 	    }
4682 	  else
4683 	    {
4684 	      hp_gamma->table[CL_RED][C] = C;
4685 	      hp_gamma->table[CL_GREEN][C] = C;
4686 	      hp_gamma->table[CL_BLUE][C] = C;
4687 	    }
4688 	}
4689 
4690       /* Locate threshold of bw */
4691       for (C = 0; C < 256; C++)
4692 	if (hp_gamma->table[CL_RED][C] != 0)
4693 	  break;
4694 
4695       bw_threshold = C - 1;
4696     }
4697   else
4698     {
4699       /* Some alloc failed */
4700       rst = ERROR;
4701 
4702       Gamma_FreeTables ();
4703     }
4704 
4705   DBG (DBG_FNC, "> Gamma_AllocTable: %i >> bw_threshold = %i\n", rst,
4706        bw_threshold);
4707 
4708   return rst;
4709 }
4710 
4711 static SANE_Int
Gamma_Apply(struct st_device * dev,SANE_Byte * Regs,struct st_scanparams * scancfg,struct st_hwdconfig * hwdcfg,struct st_gammatables * mygamma)4712 Gamma_Apply (struct st_device *dev, SANE_Byte * Regs,
4713 	     struct st_scanparams *scancfg, struct st_hwdconfig *hwdcfg,
4714 	     struct st_gammatables *mygamma)
4715 {
4716   SANE_Int rst = OK;
4717 
4718   DBG (DBG_FNC, "+ Gamma_Apply(*Regs, *scancfg, *hwdcfg, *mygamma):\n");
4719   dbg_ScanParams (scancfg);
4720 
4721   if (hwdcfg->use_gamma_tables == FALSE)
4722     {
4723       DBG (DBG_FNC, "-> Gamma tables are not used\n");
4724 
4725       v1600 = NULL;
4726       v1604 = NULL;
4727       v1608 = NULL;
4728     }
4729   else
4730     {
4731       /*390b */
4732       SANE_Int table_size, buffersize, c;
4733       SANE_Byte channels, *gammabuffer;
4734 
4735       DBG (DBG_FNC, "-> Using gamma tables\n");
4736 
4737       /* get channels count */
4738       channels = 3;		/* default */
4739 
4740       if (scancfg->colormode != CM_COLOR)
4741 	{
4742 	  if (scancfg->channel != 3)
4743 	    {
4744 	      if (scancfg->colormode != 3)
4745 		channels = (scancfg->samplerate == PIXEL_RATE) ? 2 : 1;
4746 	    }
4747 	}
4748 
4749       /* get size for gamma tables */
4750       switch (mygamma->depth & 0x0c)
4751 	{
4752 	case 0:
4753 	  table_size = 0x100 + (mygamma->depth & 1);
4754 	  break;
4755 	case 4:
4756 	  table_size = 0x400 + (mygamma->depth & 1);
4757 	  break;
4758 	case 8:
4759 	  table_size = 0x1000 + (mygamma->depth & 1);
4760 	  break;
4761 	default:
4762 	  table_size = 2;
4763 	  break;
4764 	}
4765 
4766       /* allocate space for gamma buffer */
4767       buffersize = table_size * channels;
4768       gammabuffer = (SANE_Byte *) malloc (buffersize * sizeof (SANE_Byte));
4769       if (gammabuffer != NULL)
4770 	{
4771 	  /* update gamma pointers for each channel */
4772 	  v1600 = (SANE_Byte *) & mygamma->table[CL_RED];
4773 	  v1604 = (SANE_Byte *) & mygamma->table[CL_GREEN];
4774 	  v1608 = (SANE_Byte *) & mygamma->table[CL_BLUE];
4775 
4776 	  /* include gamma tables into one buffer */
4777 	  for (c = 0; c < channels; c++)
4778 	    memcpy (gammabuffer + (c * table_size), mygamma->table[c],
4779 		    table_size);
4780 
4781 	  /* send gamma buffer to scanner */
4782 	  Write_Byte (dev->usb_handle, 0xee0b, Regs[0x060b] & 0xaf);
4783 	  rst = Gamma_SendTables (dev, Regs, gammabuffer, buffersize);
4784 	  Write_Byte (dev->usb_handle, 0xee0b, Regs[0x060b]);
4785 
4786 	  /* free gamma buffer */
4787 	  free (gammabuffer);
4788 	}
4789       else
4790 	rst = ERROR;
4791     }
4792 
4793   return rst;
4794 }
4795 
4796 static SANE_Int
Refs_Analyze_Pattern(struct st_scanparams * scancfg,SANE_Byte * scanned_pattern,SANE_Int * ler1,SANE_Int ler1order,SANE_Int * ser1,SANE_Int ser1order)4797 Refs_Analyze_Pattern (struct st_scanparams *scancfg,
4798 		      SANE_Byte * scanned_pattern, SANE_Int * ler1,
4799 		      SANE_Int ler1order, SANE_Int * ser1, SANE_Int ser1order)
4800 {
4801   SANE_Int buffersize, xpos, ypos, coord, cnt, chn_size, dist, rst;
4802   double *color_sum, *color_dif, diff_max;
4803   SANE_Int vector[3];
4804 
4805   DBG (DBG_FNC,
4806        "+ Refs_Analyze_Pattern(depth=%i, width=%i, height=%i, *scanned_pattern, *ler1, ler1order=%i, *ser1, ser1order=%i)\n",
4807        scancfg->depth, scancfg->coord.width, scancfg->coord.height, ler1order,
4808        ser1order);
4809 
4810   rst = ERROR;			/* by default */
4811   dist = 5;			/* distance to compare */
4812   chn_size = (scancfg->depth > 8) ? 2 : 1;
4813   buffersize = max (scancfg->coord.width, scancfg->coord.height);
4814 
4815   color_sum = (double *) malloc (sizeof (double) * buffersize);
4816   if (color_sum != NULL)
4817     {
4818       color_dif = (double *) malloc (sizeof (double) * buffersize);
4819       if (color_dif != NULL)
4820 	{
4821 			/*-------- 1st SER -------- */
4822 	  coord = 1;
4823 
4824 	  if ((scancfg->coord.width - dist) > 1)
4825 	    {
4826 	      /* clear buffers */
4827 	      memset (color_sum, 0, sizeof (double) * buffersize);
4828 	      memset (color_dif, 0, sizeof (double) * buffersize);
4829 
4830 	      for (xpos = 0; xpos < scancfg->coord.width; xpos++)
4831 		{
4832 		  for (ypos = 0; ypos < 20; ypos++)
4833 		    color_sum[xpos] +=
4834 		      data_lsb_get (scanned_pattern +
4835 				    (scancfg->coord.width * ypos) + xpos,
4836 				    chn_size);
4837 		}
4838 
4839 	      diff_max =
4840 		(ser1order !=
4841 		 0) ? color_sum[0] - color_sum[1] : color_sum[1] -
4842 		color_sum[0];
4843 	      color_dif[0] = diff_max;
4844 	      cnt = 1;
4845 
4846 	      do
4847 		{
4848 		  color_dif[cnt] =
4849 		    (ser1order !=
4850 		     0) ? color_sum[cnt] - color_sum[cnt +
4851 						     dist] : color_sum[cnt +
4852 								       dist] -
4853 		    color_sum[cnt];
4854 
4855 		  if ((color_dif[cnt] >= 0) && (color_dif[cnt] > diff_max))
4856 		    {
4857 		      /*d4df */
4858 		      diff_max = color_dif[cnt];
4859 		      if (abs (color_dif[cnt] - color_dif[cnt - 1]) >
4860 			  abs (color_dif[coord] - color_dif[coord - 1]))
4861 			coord = cnt;
4862 		    }
4863 
4864 		  cnt++;
4865 		}
4866 	      while (cnt < (scancfg->coord.width - dist));
4867 	    }
4868 
4869 	  vector[0] = coord + dist;
4870 
4871 			/*-------- 1st LER -------- */
4872 	  coord = 1;
4873 
4874 	  if ((scancfg->coord.height - dist) > 1)
4875 	    {
4876 	      /* clear buffers */
4877 	      memset (color_sum, 0, sizeof (double) * buffersize);
4878 	      memset (color_dif, 0, sizeof (double) * buffersize);
4879 
4880 	      for (ypos = 0; ypos < scancfg->coord.height; ypos++)
4881 		{
4882 		  for (xpos = vector[0]; xpos < scancfg->coord.width - dist;
4883 		       xpos++)
4884 		    color_sum[ypos] +=
4885 		      data_lsb_get (scanned_pattern +
4886 				    (scancfg->coord.width * ypos) + xpos,
4887 				    chn_size);
4888 		}
4889 
4890 	      diff_max =
4891 		(ler1order !=
4892 		 0) ? color_sum[0] - color_sum[1] : color_sum[1] -
4893 		color_sum[0];
4894 	      color_dif[0] = diff_max;
4895 
4896 	      cnt = 1;
4897 
4898 	      do
4899 		{
4900 		  color_dif[cnt] =
4901 		    (ler1order !=
4902 		     0) ? color_sum[cnt] - color_sum[cnt +
4903 						     dist] : color_sum[cnt +
4904 								       dist] -
4905 		    color_sum[cnt];
4906 
4907 		  if ((color_dif[cnt] >= 0) && (color_dif[cnt] > diff_max))
4908 		    {
4909 		      diff_max = color_dif[cnt];
4910 		      if (abs (color_dif[cnt] - color_dif[cnt - 1]) >
4911 			  abs (color_dif[coord] - color_dif[coord - 1]))
4912 			coord = cnt;
4913 		    }
4914 
4915 		  cnt++;
4916 		}
4917 	      while (cnt < (scancfg->coord.height - dist));
4918 	    }
4919 
4920 	  vector[1] = coord + dist;
4921 
4922 			/*-------- 1st LER -------- */
4923 	  if ((scancfg->coord.width - dist) > 1)
4924 	    {
4925 	      /* clear buffers */
4926 	      memset (color_sum, 0, sizeof (double) * buffersize);
4927 	      memset (color_dif, 0, sizeof (double) * buffersize);
4928 
4929 	      for (xpos = 0; xpos < scancfg->coord.width; xpos++)
4930 		{
4931 		  for (ypos = coord + 4; ypos < scancfg->coord.height; ypos++)
4932 		    color_sum[xpos] +=
4933 		      data_lsb_get (scanned_pattern +
4934 				    (scancfg->coord.width * ypos) + xpos,
4935 				    chn_size);
4936 		}
4937 
4938 	      diff_max =
4939 		(ser1order !=
4940 		 0) ? color_sum[0] - color_sum[1] : color_sum[1] -
4941 		color_sum[0];
4942 	      color_dif[0] = diff_max;
4943 	      cnt = 1;
4944 
4945 	      do
4946 		{
4947 		  color_dif[cnt] =
4948 		    (ser1order !=
4949 		     0) ? color_sum[cnt] - color_sum[cnt +
4950 						     dist] : color_sum[cnt +
4951 								       dist] -
4952 		    color_sum[cnt];
4953 
4954 		  if ((color_dif[cnt] >= 0) && (color_dif[cnt] > diff_max))
4955 		    {
4956 		      diff_max = color_dif[cnt];
4957 		      if (abs (color_dif[cnt] - color_dif[cnt - 1]) >
4958 			  abs (color_dif[coord] - color_dif[coord - 1]))
4959 			coord = cnt;
4960 		    }
4961 
4962 		  cnt++;
4963 		}
4964 	      while (cnt < (scancfg->coord.width - dist));
4965 	    }
4966 
4967 	  vector[2] = coord + dist;
4968 
4969 	  /* save image */
4970 	  if (RTS_Debug->SaveCalibFile != FALSE)
4971 	    dbg_autoref (scancfg, scanned_pattern, vector[0], vector[2],
4972 			 vector[1]);
4973 
4974 	  /* assign values detected */
4975 	  if (ser1 != NULL)
4976 	    *ser1 = vector[2];
4977 
4978 	  if (ler1 != NULL)
4979 	    *ler1 = vector[1];
4980 
4981 	  /* show values */
4982 	  DBG (DBG_FNC, " -> Vectors found: x1=%i, x2=%i, y=%i\n", vector[0],
4983 	       vector[2], vector[1]);
4984 
4985 	  rst = OK;
4986 
4987 	  free (color_dif);
4988 	}
4989 
4990       free (color_sum);
4991     }
4992 
4993   DBG (DBG_FNC, "- Refs_Analyze_Pattern: %i\n", rst);
4994 
4995   return rst;
4996 }
4997 
4998 static double
get_shrd(double value,SANE_Int desp)4999 get_shrd (double value, SANE_Int desp)
5000 {
5001   if (desp <= 0x40)
5002     return value / pow (2, desp);
5003   else
5004     return 0;
5005 }
5006 
5007 static char
get_byte(double value)5008 get_byte (double value)
5009 {
5010   unsigned int data;
5011   double temp;
5012 
5013   if (value > 0xffffffff)
5014     {
5015       temp = floor (get_shrd (value, 0x20));
5016       temp *= pow (2, 32);
5017       value -= temp;
5018     }
5019 
5020   data = (unsigned int) value;
5021 
5022   data = _B0 (data);
5023 
5024   return data;
5025 }
5026 
5027 static SANE_Int
Timing_SetLinearImageSensorClock(SANE_Byte * Regs,struct st_cph * cph)5028 Timing_SetLinearImageSensorClock (SANE_Byte * Regs, struct st_cph *cph)
5029 {
5030   SANE_Int rst = ERROR;
5031 
5032   DBG (DBG_FNC,
5033        "+ Timing_SetLinearImageSensorClock(SANE_Byte *Regs, struct st_cph *cph)\n");
5034 
5035   dbg_sensorclock (cph);
5036 
5037   if ((Regs != NULL) && (cph != NULL))
5038     {
5039       Regs[0x00] = get_byte (cph->p1);
5040       Regs[0x01] = get_byte (get_shrd (cph->p1, 0x08));
5041       Regs[0x02] = get_byte (get_shrd (cph->p1, 0x10));
5042       Regs[0x03] = get_byte (get_shrd (cph->p1, 0x18));
5043 
5044       Regs[0x04] &= 0x80;
5045       Regs[0x04] |= ((get_byte (get_shrd (cph->p1, 0x20))) & 0x0f);
5046       Regs[0x04] |= ((cph->ps & 1) << 6);
5047       Regs[0x04] |= ((cph->ge & 1) << 5);
5048       Regs[0x04] |= ((cph->go & 1) << 4);
5049 
5050       Regs[0x05] = get_byte (cph->p2);
5051       Regs[0x06] = get_byte (get_shrd (cph->p2, 0x08));
5052       Regs[0x07] = get_byte (get_shrd (cph->p2, 0x10));
5053       Regs[0x08] = get_byte (get_shrd (cph->p2, 0x18));
5054       Regs[0x09] &= 0xf0;
5055       Regs[0x09] |= ((get_byte (get_shrd (cph->p2, 0x20))) & 0x0f);
5056 
5057       rst = OK;
5058     }
5059 
5060   DBG (DBG_FNC, "- Timing_SetLinearImageSensorClock: %i\n", rst);
5061 
5062   return rst;
5063 }
5064 
5065 static void
RTS_Setup_SensorTiming(struct st_device * dev,SANE_Int mytiming,SANE_Byte * Regs)5066 RTS_Setup_SensorTiming (struct st_device *dev, SANE_Int mytiming,
5067 			SANE_Byte * Regs)
5068 {
5069   DBG (DBG_FNC, "+ RTS_Setup_SensorTiming(mytiming=%i, *Regs):\n", mytiming);
5070 
5071   if ((Regs != NULL) && (mytiming < dev->timings_count))
5072     {
5073       struct st_timing *mt = dev->timings[mytiming];
5074 
5075       if (mt != NULL)
5076 	{
5077 	  dbg_timing (mt);
5078 
5079 	  /* Correlated-Double-Sample 1 & 2 */
5080 	  data_bitset (&Regs[0x92], 0x3f, mt->cdss[0]);
5081 	  data_bitset (&Regs[0x93], 0x3f, mt->cdsc[0]);
5082 	  data_bitset (&Regs[0x94], 0x3f, mt->cdss[1]);
5083 	  data_bitset (&Regs[0x95], 0x3f, mt->cdsc[1]);
5084 
5085 	  data_bitset (&Regs[0x96], 0x3f, mt->cnpp);
5086 
5087 	  /* Linear image sensor transfer gates */
5088 	  data_bitset (&Regs[0x45], 0x80, mt->cvtrp[0]);
5089 	  data_bitset (&Regs[0x45], 0x40, mt->cvtrp[1]);
5090 	  data_bitset (&Regs[0x45], 0x20, mt->cvtrp[2]);
5091 
5092 	  data_bitset (&Regs[0x45], 0x1f, mt->cvtrfpw);
5093 	  data_bitset (&Regs[0x46], 0x1f, mt->cvtrbpw);
5094 
5095 	  data_lsb_set (&Regs[0x47], mt->cvtrw, 1);
5096 
5097 	  data_lsb_set (&Regs[0x84], mt->cphbp2s, 3);
5098 	  data_lsb_set (&Regs[0x87], mt->cphbp2e, 3);
5099 
5100 	  data_lsb_set (&Regs[0x8a], mt->clamps, 3);
5101 	  data_lsb_set (&Regs[0x8d], mt->clampe, 3);
5102 
5103 	  if (dev->chipset->model == RTS8822L_02A)
5104 	    {
5105 	      if (mt->clampe == -1)
5106 		data_lsb_set (&Regs[0x8d], mt->cphbp2e, 3);
5107 	    }
5108 
5109 	  Regs[0x97] = get_byte (mt->adcclkp[0]);
5110 	  Regs[0x98] = get_byte (get_shrd (mt->adcclkp[0], 0x08));
5111 	  Regs[0x99] = get_byte (get_shrd (mt->adcclkp[0], 0x10));
5112 	  Regs[0x9a] = get_byte (get_shrd (mt->adcclkp[0], 0x18));
5113 	  Regs[0x9b] &= 0xf0;
5114 	  Regs[0x9b] |= ((get_byte (get_shrd (mt->adcclkp[0], 0x20))) & 0x0f);
5115 
5116 	  Regs[0xc1] = get_byte (mt->adcclkp[1]);
5117 	  Regs[0xc2] = get_byte (get_shrd (mt->adcclkp[1], 0x08));
5118 	  Regs[0xc3] = get_byte (get_shrd (mt->adcclkp[1], 0x10));
5119 	  Regs[0xc4] = get_byte (get_shrd (mt->adcclkp[1], 0x18));
5120 	  Regs[0xc5] &= 0xe0;
5121 	  Regs[0xc5] |= ((get_byte (get_shrd (mt->adcclkp[1], 0x20))) & 0x0f);
5122 
5123 	  /* bit(4) = bit(0) */
5124 	  Regs[0xc5] |= ((mt->adcclkp2e & 1) << 4);
5125 
5126 	  Timing_SetLinearImageSensorClock (&Regs[0x48], &mt->cph[0]);
5127 	  Timing_SetLinearImageSensorClock (&Regs[0x52], &mt->cph[1]);
5128 	  Timing_SetLinearImageSensorClock (&Regs[0x5c], &mt->cph[2]);
5129 	  Timing_SetLinearImageSensorClock (&Regs[0x66], &mt->cph[3]);
5130 	  Timing_SetLinearImageSensorClock (&Regs[0x70], &mt->cph[4]);
5131 	  Timing_SetLinearImageSensorClock (&Regs[0x7a], &mt->cph[5]);
5132 	}
5133     }
5134 }
5135 
5136 static SANE_Int
Motor_GetFromResolution(SANE_Int resolution)5137 Motor_GetFromResolution (SANE_Int resolution)
5138 {
5139   SANE_Int ret;
5140 
5141   ret = 3;
5142   if (RTS_Debug->usbtype != USB11)
5143     {
5144       if (scan.scantype != ST_NORMAL)
5145 	{
5146 	  /* scantype is ST_NEG or ST_TA */
5147 	  if (resolution >= 600)
5148 	    ret = 0;
5149 	}
5150       else if (resolution >= 1200)
5151 	ret = 0;
5152     }
5153   else if (resolution >= 600)
5154     ret = 0;
5155 
5156   DBG (DBG_FNC, "> Motor_GetFromResolution(resolution=%i): %i\n", resolution,
5157        ret);
5158 
5159   return ret;
5160 }
5161 
5162 static SANE_Int
SetMultiExposure(struct st_device * dev,SANE_Byte * Regs)5163 SetMultiExposure (struct st_device *dev, SANE_Byte * Regs)
5164 {
5165   SANE_Int iValue, myctpc;
5166 
5167   DBG (DBG_FNC, "> SetMultiExposure:\n");
5168 
5169   /* set motor has no curves */
5170   data_bitset (&Regs[0xdf], 0x10, 0);	   /*---0----*/
5171 
5172   /* select case systemclock */
5173   switch (Regs[0x00] & 0x0f)
5174     {
5175     case 0x00:
5176       iValue = 0x00895440;
5177       break;			/*  3 x 0x2DC6C0 */
5178     case 0x08:
5179     case 0x01:
5180       iValue = 0x00b71b00;
5181       break;			/*  4 x 0x2DC6C0 */
5182     case 0x02:
5183       iValue = 0x0112a880;
5184       break;			/*  6 x 0x2DC6C0 */
5185     case 0x0a:
5186     case 0x03:
5187       iValue = 0x016e3600;
5188       break;			/*  8 x 0x2DC6C0 */
5189     case 0x04:
5190       iValue = 0x02255100;
5191       break;			/* 12 x 0x2DC6C0 */
5192     case 0x0c:
5193       iValue = 0x02dc6c00;
5194       break;			/* 16 x 0x2DC6C0 */
5195     case 0x05:
5196       iValue = 0x044aa200;
5197       break;			/* 24 x 0x2DC6C0 */
5198     case 0x0d:
5199       iValue = 0x05b8d800;
5200       break;			/* 32 x 0x2DC6C0 */
5201 
5202     case 0x09:
5203       iValue = 0x00f42400;
5204       break;
5205     case 0x0b:
5206       iValue = 0x01e84800;
5207       break;			/* = case 9 * 2 */
5208     default:
5209       iValue = 0x0478f7f8;
5210       break;
5211     }
5212 
5213   /* divide by timing.cnpp */
5214   iValue /= ((Regs[0x96] & 0x3f) + 1);
5215   iValue /= dev->motorcfg->basespeedpps;
5216 
5217   /* get line exposure time */
5218   myctpc = data_lsb_get (&Regs[0x30], 3) + 1;
5219 
5220   DBG (DBG_FNC, "CTPC -- SetMultiExposure -- 1 =%i\n", myctpc);
5221 
5222   /* if last step of accurve.normalscan table is lower than iValue ... */
5223   if (data_lsb_get (&Regs[0xe1], 3) < iValue)
5224     {
5225       SANE_Int traget;
5226       SANE_Int step_size = _B0 (Regs[0xe0]) + 1;
5227 
5228       /* set exposure time [RED] if zero */
5229       if (data_lsb_get (&Regs[0x36], 3) == 0)
5230 	data_lsb_set (&Regs[0x36], myctpc - 1, 3);
5231 
5232       /* set exposure time [GREEN] if zero */
5233       if (data_lsb_get (&Regs[0x3c], 3) == 0)
5234 	data_lsb_set (&Regs[0x3c], myctpc - 1, 3);
5235 
5236       /* set exposure time [BLUE] if zero */
5237       if (data_lsb_get (&Regs[0x42], 3) == 0)
5238 	data_lsb_set (&Regs[0x42], myctpc - 1, 3);
5239 
5240       iValue = (iValue + 1) * step_size;
5241 
5242       /* update line exposure time */
5243       traget = (((myctpc + iValue - 1) / myctpc) * myctpc);
5244       data_lsb_set (&Regs[0x30], traget - 1, 3);
5245 
5246       traget = (traget / step_size) - 1;
5247       data_lsb_set (&Regs[0x00e1], traget, 3);
5248     }
5249 
5250   /* 8300 */
5251   return OK;
5252 }
5253 
5254 static SANE_Int
data_lsb_get(SANE_Byte * address,SANE_Int size)5255 data_lsb_get (SANE_Byte * address, SANE_Int size)
5256 {
5257   SANE_Int ret = 0;
5258   if ((address != NULL) && (size > 0) && (size < 5))
5259     {
5260       SANE_Int a;
5261       SANE_Byte b;
5262       size--;
5263       for (a = size; a >= 0; a--)
5264 	{
5265 	  b = address[a];
5266 	  ret = (ret << 8) + b;
5267 	}
5268     }
5269   return ret;
5270 }
5271 
5272 static SANE_Byte
data_bitget(SANE_Byte * address,SANE_Int mask)5273 data_bitget (SANE_Byte * address, SANE_Int mask)
5274 {
5275   SANE_Int desp = 0;
5276 
5277   if (mask & 1);
5278   else if (mask & 2)
5279     desp = 1;
5280   else if (mask & 4)
5281     desp = 2;
5282   else if (mask & 8)
5283     desp = 3;
5284   else if (mask & 16)
5285     desp = 4;
5286   else if (mask & 32)
5287     desp = 5;
5288   else if (mask & 64)
5289     desp = 6;
5290   else if (mask & 128)
5291     desp = 7;
5292 
5293   return (*address & mask) >> desp;
5294 }
5295 
5296 static void
data_bitset(SANE_Byte * address,SANE_Int mask,SANE_Byte data)5297 data_bitset (SANE_Byte * address, SANE_Int mask, SANE_Byte data)
5298 {
5299   /* This function fills mask bits of just a byte with bits given in data */
5300   if (mask & 1);
5301   else if (mask & 2)
5302     data <<= 1;
5303   else if (mask & 4)
5304     data <<= 2;
5305   else if (mask & 8)
5306     data <<= 3;
5307   else if (mask & 16)
5308     data <<= 4;
5309   else if (mask & 32)
5310     data <<= 5;
5311   else if (mask & 64)
5312     data <<= 6;
5313   else if (mask & 128)
5314     data <<= 7;
5315 
5316   *address = (*address & (0xff - mask)) | (data & mask);
5317 }
5318 
5319 static void
data_wide_bitset(SANE_Byte * address,SANE_Int mask,SANE_Int data)5320 data_wide_bitset (SANE_Byte * address, SANE_Int mask, SANE_Int data)
5321 {
5322   /* Setting bytes bit per bit
5323      mask is 4 bytes size
5324      Example:
5325      data  = 0111010111
5326      mask  = 00000000 11111111 11000000 00000000
5327      rst   = 00000000 01110101 11000000 00000000 */
5328 
5329   SANE_Int mymask, started = FALSE;
5330 
5331   if ((address != NULL) && (mask != 0))
5332     {
5333       while (mask != 0)
5334 	{
5335 	  mymask = _B0 (mask);
5336 
5337 	  if (started == FALSE)
5338 	    {
5339 	      if (mymask != 0)
5340 		{
5341 		  SANE_Int a, myvalue;
5342 
5343 		  for (a = 0; a < 8; a++)
5344 		    if ((mymask & (1 << a)) != 0)
5345 		      break;
5346 
5347 		  myvalue = _B0 (data << a);
5348 		  myvalue >>= a;
5349 		  data_bitset (address, mymask, myvalue);
5350 		  data >>= (8 - a);
5351 		  started = TRUE;
5352 		}
5353 	    }
5354 	  else
5355 	    {
5356 	      data_bitset (address, mymask, _B0 (data));
5357 	      data >>= 8;
5358 	    }
5359 
5360 	  address++;
5361 	  mask >>= 8;
5362 	}
5363     }
5364 }
5365 
5366 
5367 static void
data_lsb_set(SANE_Byte * address,SANE_Int data,SANE_Int size)5368 data_lsb_set (SANE_Byte * address, SANE_Int data, SANE_Int size)
5369 {
5370   if ((address != NULL) && (size > 0) && (size < 5))
5371     {
5372       SANE_Int a;
5373       for (a = 0; a < size; a++)
5374 	{
5375 	  address[a] = _B0 (data);
5376 	  data >>= 8;
5377 	}
5378     }
5379 }
5380 
5381 static void
data_msb_set(SANE_Byte * address,SANE_Int data,SANE_Int size)5382 data_msb_set (SANE_Byte * address, SANE_Int data, SANE_Int size)
5383 {
5384   if ((address != NULL) && (size > 0) && (size < 5))
5385     {
5386       SANE_Int a;
5387 
5388       for (a = size - 1; a >= 0; a--)
5389 	{
5390 	  address[a] = _B0 (data);
5391 	  data >>= 8;
5392 	}
5393     }
5394 }
5395 
5396 static SANE_Int
data_swap_endianess(SANE_Int address,SANE_Int size)5397 data_swap_endianess (SANE_Int address, SANE_Int size)
5398 {
5399   SANE_Int rst = 0;
5400 
5401   if ((size > 0) && (size < 5))
5402     {
5403       SANE_Int a;
5404 
5405       for (a = 0; a < size; a++)
5406 	{
5407 	  rst = (rst << 8) | _B0 (address);
5408 	  address >>= 8;
5409 	}
5410     }
5411 
5412   return rst;
5413 }
5414 
5415 static void
Lamp_SetGainMode(struct st_device * dev,SANE_Byte * Regs,SANE_Int resolution,SANE_Byte gainmode)5416 Lamp_SetGainMode (struct st_device *dev, SANE_Byte * Regs,
5417 		  SANE_Int resolution, SANE_Byte gainmode)
5418 {
5419   DBG (DBG_FNC, "> Lamp_SetGainMode(*Regs, resolution=%i, gainmode=%i):\n",
5420        resolution, gainmode);
5421 
5422   if (dev->chipset->model == RTS8822L_02A)
5423     {
5424       /* hp4370 */
5425       SANE_Int data1, data2;
5426 
5427       data1 = data_lsb_get (&Regs[0x154], 2) & 0xfe7f;
5428       data2 = data_lsb_get (&Regs[0x156], 2);
5429 
5430       switch (resolution)
5431 	{
5432 	case 4800:
5433 	  data2 |= 0x40;
5434 	  data1 &= 0xffbf;
5435 	  break;
5436 	case 100:
5437 	case 150:
5438 	case 200:
5439 	case 300:
5440 	case 600:
5441 	case 1200:
5442 	case 2400:
5443 	  data1 |= 0x40;
5444 	  data2 &= 0xffbf;
5445 	  break;
5446 	}
5447 
5448       data_lsb_set (&Regs[0x154], data1, 2);
5449       data_lsb_set (&Regs[0x156], data2, 2);
5450     }
5451   else
5452     {
5453       /* hp3970 hp4070 ua4900 */
5454       SANE_Int data;
5455 
5456       data = data_lsb_get (&Regs[0x154], 2) & 0xfe7f;
5457       data = (gainmode == FALSE) ? data | 0x0040 : data & 0xffbf;
5458 
5459       switch (resolution)
5460 	{
5461 	case 100:
5462 	case 200:
5463 	case 300:
5464 	case 600:
5465 	  data |= 0x0100;
5466 	  break;
5467 	case 2400:
5468 	  data |= 0x0180;
5469 	  break;
5470 	case 1200:
5471 	  if (dev->sensorcfg->type == CIS_SENSOR)
5472 	    data |= 0x80;
5473 	  else if (dev->sensorcfg->type == CCD_SENSOR)
5474 	    data |= 0x0180;
5475 	  break;
5476 	}
5477 
5478       data_lsb_set (&Regs[0x0154], data, 2);
5479     }
5480 }
5481 
5482 static SANE_Int
RTS_Scanner_StartScan(struct st_device * dev)5483 RTS_Scanner_StartScan (struct st_device *dev)
5484 {
5485   SANE_Int rst = ERROR;		/* default */
5486   SANE_Int data;
5487 
5488   DBG (DBG_FNC, "+ RTS_Scanner_StartScan():\n");
5489 
5490   v14b4 = 1;			/* TEMPORAL */
5491   data = 0;
5492   Lamp_PWM_DutyCycle_Get (dev, &data);
5493   data = _B0 (data);
5494 
5495   DBG (DBG_FNC, "->   Pwm used = %i\n", data);
5496 
5497   /*
5498      windows driver saves pwm used, in file usbfile
5499      Section [SCAN_PARAM], field PwmUsed
5500    */
5501 
5502   dev->status->cancel = FALSE;
5503 
5504   if (Scan_Start (dev) == OK)
5505     {
5506       SANE_Int transferred;
5507 
5508       rst = OK;
5509 
5510       if (dev->scanning->imagebuffer != NULL)
5511 	{
5512 	  free (dev->scanning->imagebuffer);
5513 	  dev->scanning->imagebuffer = NULL;
5514 	}
5515 
5516       SetLock (dev->usb_handle, NULL, (scan2.depth == 16) ? FALSE : TRUE);
5517 
5518       /* Reservamos los buffers necesarios para leer la imagen */
5519       Reading_CreateBuffers (dev);
5520 
5521       if (dev->Resize->type != RSZ_NONE)
5522 	Resize_Start (dev, &transferred);	/* 6729 */
5523 
5524       RTS_ScanCounter_Inc (dev);
5525     }
5526 
5527   DBG (DBG_FNC, "- RTS_Scanner_StartScan: %i\n", rst);
5528 
5529   return rst;
5530 }
5531 
5532 static void
Triplet_Gray(SANE_Byte * pPointer1,SANE_Byte * pPointer2,SANE_Byte * buffer,SANE_Int channels_count)5533 Triplet_Gray (SANE_Byte * pPointer1, SANE_Byte * pPointer2,
5534 	      SANE_Byte * buffer, SANE_Int channels_count)
5535 {
5536   /*
5537      pPointer1 = FAB8
5538      pPointer2 = FABC
5539      buffer    = FAC0
5540      channels_count = FAC4
5541    */
5542 
5543   SANE_Int value;
5544   SANE_Int channel_size;
5545 
5546   DBG (DBG_FNC,
5547        "> Triplet_Gray(*pPointer1, *pPointer2, *buffer, channels_count=%i)\n",
5548        channels_count);
5549 
5550   channel_size = (scan2.depth > 8) ? 2 : 1;
5551   channels_count = channels_count / 2;
5552 
5553   while (channels_count > 0)
5554     {
5555       value = data_lsb_get (pPointer1, channel_size);
5556       data_lsb_set (buffer, value, channel_size);
5557 
5558       value = data_lsb_get (pPointer2, channel_size);
5559       data_lsb_set (buffer + channel_size, value, channel_size);
5560 
5561       pPointer1 += 2 * channel_size;
5562       pPointer2 += 2 * channel_size;
5563       buffer += 2 * channel_size;
5564 
5565       channels_count--;
5566     }
5567 }
5568 
5569 static void
Triplet_Lineart(SANE_Byte * pPointer1,SANE_Byte * pPointer2,SANE_Byte * buffer,SANE_Int channels_count)5570 Triplet_Lineart (SANE_Byte * pPointer1, SANE_Byte * pPointer2,
5571 		 SANE_Byte * buffer, SANE_Int channels_count)
5572 {
5573   /* Composing colour in lineart mode */
5574 
5575   SANE_Int dots_count = 0;
5576   SANE_Int channel;
5577   SANE_Byte mask;
5578   SANE_Byte value;
5579   SANE_Int C;
5580 
5581   DBG (DBG_FNC,
5582        "> Triplet_Lineart(*pPointer1, *pPointer2, *buffer, channels_count=%i)\n",
5583        channels_count);
5584 
5585   if (channels_count > 0)
5586     {
5587       dots_count = (channels_count + 1) / 2;
5588       while (dots_count > 0)
5589 	{
5590 	  mask = 0x80;
5591 	  channel = 2;
5592 	  do
5593 	    {
5594 	      value = 0;
5595 	      for (C = 4; C > 0; C--)
5596 		{
5597 		  value =
5598 		    (value << 2) +
5599 		    (((*pPointer2 & mask) << 1) | (*pPointer1 & mask));
5600 		  mask = mask >> 1;
5601 		}
5602 	      *buffer = value;
5603 	      buffer++;
5604 	      channel--;
5605 	    }
5606 	  while (channel > 0);
5607 	  pPointer2 += 2;
5608 	  pPointer1 += 2;
5609 	  dots_count--;
5610 	}
5611     }
5612 }
5613 
5614 static SANE_Int
Arrange_NonColour(struct st_device * dev,SANE_Byte * buffer,SANE_Int buffer_size,SANE_Int * transferred)5615 Arrange_NonColour (struct st_device *dev, SANE_Byte * buffer,
5616 		   SANE_Int buffer_size, SANE_Int * transferred)
5617 {
5618   /*
5619      buffer : fadc
5620      buffer_size : fae0
5621    */
5622 
5623   SANE_Int lines_count = 0;	/* ebp */
5624   SANE_Int channels_count = 0;	/* fadc pisa buffer */
5625   SANE_Int rst = ERROR;
5626   struct st_scanning *scn;
5627 
5628   DBG (DBG_FNC,
5629        "+ Arrange_NonColour(*buffer, buffer_size=%i, *transferred):\n",
5630        buffer_size);
5631 
5632   /* this is just to make code more legible */
5633   scn = dev->scanning;
5634 
5635   if (scn->imagebuffer == NULL)
5636     {
5637       if ((scn->arrange_hres == TRUE) || (scan2.colormode == CM_LINEART))
5638 	{
5639 	  scn->bfsize = (scn->arrange_sensor_evenodd_dist + 1) * line_size;
5640 	  scn->imagebuffer =
5641 	    (SANE_Byte *) malloc (scn->bfsize * sizeof (SANE_Byte));
5642 	  if (scn->imagebuffer != NULL)
5643 	    {
5644 	      if (Read_Block (dev, scn->bfsize, scn->imagebuffer, transferred)
5645 		  == OK)
5646 		{
5647 		  scn->channel_size = (scan2.depth == 8) ? 1 : 2;
5648 		  scn->desp1[CL_RED] = 0;
5649 		  scn->desp2[CL_RED] =
5650 		    scn->channel_size +
5651 		    (scn->arrange_sensor_evenodd_dist * line_size);
5652 		  scn->pColour2[CL_RED] =
5653 		    scn->imagebuffer + scn->desp2[CL_RED];
5654 		  scn->pColour1[CL_RED] =
5655 		    scn->imagebuffer + scn->desp1[CL_RED];
5656 		  rst = OK;
5657 		}
5658 	    }
5659 	}
5660     }
5661   else
5662     rst = OK;
5663 
5664   /* b0f4 */
5665   if (rst == OK)
5666     {
5667       scn->imagepointer = scn->imagebuffer;
5668       lines_count = buffer_size / line_size;
5669       channels_count = line_size / scn->channel_size;
5670       while (lines_count > 0)
5671 	{
5672 	  if (scan2.colormode == CM_LINEART)
5673 	    Triplet_Lineart (scn->pColour1[CL_RED], scn->pColour2[CL_RED],
5674 			     buffer, channels_count);
5675 	  else
5676 	    Triplet_Gray (scn->pColour1[CL_RED], scn->pColour2[CL_RED],
5677 			  buffer, channels_count);
5678 
5679 	  buffer += line_size;
5680 	  scn->arrange_size -= bytesperline;
5681 
5682 	  lines_count--;
5683 	  if (lines_count == 0)
5684 	    {
5685 	      if ((scn->arrange_size | v15bc) == 0)
5686 		break;
5687 	    }
5688 
5689 	  rst = Read_Block (dev, line_size, scn->imagepointer, transferred);
5690 	  if (rst != OK)
5691 	    break;
5692 
5693 	  if (scn->arrange_hres == TRUE)
5694 	    {
5695 	      scn->desp2[CL_RED] =
5696 		(line_size + scn->desp2[CL_RED]) % scn->bfsize;
5697 	      scn->desp1[CL_RED] =
5698 		(line_size + scn->desp1[CL_RED]) % scn->bfsize;
5699 
5700 	      scn->pColour2[CL_RED] = scn->imagebuffer + scn->desp2[CL_RED];
5701 	      scn->pColour1[CL_RED] = scn->imagebuffer + scn->desp1[CL_RED];
5702 	    }
5703 
5704 	  /* b21d */
5705 	  scn->imagepointer += line_size;
5706 	  if (scn->imagepointer >= (scn->imagebuffer + scn->bfsize))
5707 	    scn->imagepointer = scn->imagebuffer;
5708 	}
5709     }
5710 
5711   /* 2246 */
5712 
5713   DBG (DBG_FNC, "- Arrange_NonColour(*transferred=%i): %i\n", *transferred,
5714        rst);
5715 
5716   return rst;
5717 }
5718 
5719 static SANE_Int
Resize_Decrease(SANE_Byte * to_buffer,SANE_Int to_resolution,SANE_Int to_width,SANE_Byte * from_buffer,SANE_Int from_resolution,SANE_Int from_width,SANE_Int myresize_mode)5720 Resize_Decrease (SANE_Byte * to_buffer, SANE_Int to_resolution,
5721 		 SANE_Int to_width, SANE_Byte * from_buffer,
5722 		 SANE_Int from_resolution, SANE_Int from_width,
5723 		 SANE_Int myresize_mode)
5724 {
5725   /*
5726      to_buffer = FAC8 = 0x236200
5727      to_resolution      = FACC = 0x4b
5728      to_width    = FAD0 = 0x352
5729      from_buffer = FAD4 = 0x235460
5730      from_resolution      = FAD8 = 0x64
5731      from_width    = FADC = 0x46d
5732      myresize_mode   = FAE0 = 1
5733    */
5734 
5735   SANE_Int rst = ERROR;
5736   SANE_Int channels = 0;	/* fac8 */
5737   SANE_Int depth = 0;		/* fae0 */
5738   SANE_Int color[3] = { 0, 0, 0 };	/* fab8 | fabc | fac0 */
5739   SANE_Int to_pos = 0;		/* fad4 */
5740   SANE_Int rescont = 0;
5741   SANE_Int from_pos = 0;	/* fab4 */
5742   SANE_Int C;
5743   SANE_Int smres = 0;		/* fab0 */
5744   SANE_Int value;
5745   SANE_Int channel_size;
5746 
5747   to_resolution = to_resolution & 0xffff;
5748   from_resolution = from_resolution & 0xffff;
5749 
5750   DBG (DBG_FNC,
5751        "+ Resize_Decrease(*to_buffer, to_resolution=%i, to_width=%i, *from_buffer, from_resolution=%i, from_width=%i, myresize_mode=%i):\n",
5752        to_resolution, to_width, from_resolution, from_width, myresize_mode);
5753 
5754   if (myresize_mode != RSZ_LINEART)
5755     {
5756       switch (myresize_mode)
5757 	{
5758 	case RSZ_GRAYL:
5759 	  channels = 1;
5760 	  depth = 8;
5761 	  break;
5762 	case RSZ_COLOURL:
5763 	  channels = 3;
5764 	  depth = 8;
5765 	  break;
5766 	case RSZ_COLOURH:
5767 	  channels = 3;
5768 	  depth = 16;
5769 	  break;
5770 	case RSZ_GRAYH:
5771 	  channels = 1;
5772 	  depth = 16;
5773 	  break;
5774 	}
5775 
5776       channel_size = (depth > 8) ? 2 : 1;
5777       to_pos = 0;
5778       rescont = 0;
5779 
5780       while (to_pos < to_width)
5781 	{
5782 	  from_pos++;
5783 	  if (from_pos > from_width)
5784 	    from_buffer -= (((depth + 7) / 8) * channels);
5785 
5786 	  rescont += to_resolution;
5787 	  if (rescont < from_resolution)
5788 	    {
5789 	      /* Adds 3 color channel values */
5790 	      for (C = 0; C < channels; C++)
5791 		{
5792 		  color[C] +=
5793 		    data_lsb_get (from_buffer, channel_size) * to_resolution;
5794 		  from_buffer += channel_size;
5795 		}
5796 	    }
5797 	  else
5798 	    {
5799 	      /* fc3c */
5800 	      to_pos++;
5801 	      smres = to_resolution - (rescont - from_resolution);
5802 	      for (C = 0; C < channels; C++)
5803 		{
5804 		  value =
5805 		    ((data_lsb_get (from_buffer, channel_size) * smres) +
5806 		     color[C]) / from_resolution;
5807 		  data_lsb_set (to_buffer, value, channel_size);
5808 		  color[C] =
5809 		    data_lsb_get (from_buffer,
5810 				  channel_size) * (rescont - from_resolution);
5811 
5812 		  to_buffer += channel_size;
5813 		  from_buffer += channel_size;
5814 		}
5815 	      rescont -= from_resolution;
5816 	    }
5817 	}
5818 
5819       rst = OK;
5820     }
5821   else
5822     {
5823       /* fd60 */
5824       SANE_Int bit, pos, desp, rescont2;
5825 
5826       *to_buffer = 0;
5827       bit = 0;
5828       pos = 0;
5829       desp = 0;
5830       rescont = 0;
5831       rescont2 = 0;
5832       if (to_width > 0)
5833 	{
5834 	  do
5835 	    {
5836 	      if (bit == 8)
5837 		{
5838 		  /* fda6 */
5839 		  bit = 0;
5840 		  to_buffer++;
5841 		  *to_buffer = 0;
5842 		}
5843 
5844 	      rescont += to_resolution;
5845 	      if (rescont < from_resolution)
5846 		{
5847 		  if ((*from_buffer & (0x80 >> desp)) != 0)
5848 		    rescont2 += to_resolution;
5849 		}
5850 	      else
5851 		{
5852 		  /*fdd5 */
5853 		  pos++;
5854 		  rescont -= from_resolution;
5855 		  if ((*from_buffer & (0x80 >> desp)) != 0)
5856 		    /*fdee */
5857 		    rescont2 += (to_resolution - rescont);
5858 		  if (rescont2 > (to_resolution / 2))
5859 		    /* fe00 */
5860 		    *to_buffer = _B0 (*to_buffer | (0x80 >> bit));
5861 		  rescont2 =
5862 		    ((*from_buffer & (0x80 >> desp)) != 0) ? rescont : 0;
5863 		  bit++;
5864 		}
5865 
5866 	      /* fe2f */
5867 	      desp++;
5868 	      if (desp == 8)
5869 		{
5870 		  desp = 0;
5871 		  from_buffer++;
5872 		}
5873 	    }
5874 	  while (pos < to_width);
5875 	}
5876       else
5877 	rst = OK;
5878     }
5879 
5880   DBG (DBG_FNC, "- Resize_Decrease: %i\n", rst);
5881 
5882   return rst;
5883 }
5884 
5885 static SANE_Int
Resize_Increase(SANE_Byte * to_buffer,SANE_Int to_resolution,SANE_Int to_width,SANE_Byte * from_buffer,SANE_Int from_resolution,SANE_Int from_width,SANE_Int myresize_mode)5886 Resize_Increase (SANE_Byte * to_buffer, SANE_Int to_resolution,
5887 		 SANE_Int to_width, SANE_Byte * from_buffer,
5888 		 SANE_Int from_resolution, SANE_Int from_width,
5889 		 SANE_Int myresize_mode)
5890 {
5891   /*
5892 
5893      to_buffer       = FAC8 = 0x2353f0
5894      to_resolution   = FACC = 0x4b
5895      to_width        = FAD0 = 0x352
5896      from_buffer     = FAD4 = 0x234650
5897      from_resolution = FAD8 = 0x64
5898      from_width      = FADC = 0x46d
5899      myresize_mode   = FAE0 = 1
5900    */
5901 
5902   SANE_Int rst = ERROR;
5903   SANE_Int desp;		/* fac0 */
5904   SANE_Byte *myp2;		/* faac */
5905   SANE_Int mywidth;		/* fab4 fab8 */
5906   SANE_Int mychannels;		/* fabc */
5907   SANE_Int channels = 0;	/* faa4 */
5908   SANE_Int depth = 0;		/* faa8 */
5909   SANE_Int pos = 0;		/* fae0 */
5910   SANE_Int rescount;
5911   SANE_Int val6 = 0;
5912   SANE_Int val7 = 0;
5913   SANE_Int value;
5914   /**/
5915     DBG (DBG_FNC,
5916 	 "+ Resize_Increase(*to_buffer, to_resolution=%i, to_width=%i, *from_buffer, from_resolution=%i, from_width=%i, myresize_mode=%i):\n",
5917 	 to_resolution, to_width, from_resolution, from_width, myresize_mode);
5918 
5919   if (myresize_mode != RSZ_LINEART)
5920     {
5921       switch (myresize_mode)
5922 	{
5923 	case RSZ_GRAYL:
5924 	  channels = 1;
5925 	  depth = 8;
5926 	  break;
5927 	case RSZ_COLOURL:
5928 	  channels = 3;
5929 	  depth = 8;
5930 	  break;
5931 	case RSZ_COLOURH:
5932 	  channels = 3;
5933 	  depth = 16;
5934 	  break;
5935 	case RSZ_GRAYH:
5936 	  channels = 1;
5937 	  depth = 16;
5938 	  break;
5939 	}
5940 
5941       if (channels > 0)
5942 	{
5943 	  SANE_Byte channel_size;
5944 	  SANE_Byte *p_dst;	/* fac8 */
5945 	  SANE_Byte *p_src;	/* fad4 */
5946 
5947 	  desp = to_buffer - from_buffer;
5948 	  myp2 = from_buffer;
5949 	  channel_size = (depth == 8) ? 1 : 2;
5950 
5951 	  for (mychannels = 0; mychannels < channels; mychannels++)
5952 	    {
5953 	      pos = 0;
5954 	      rescount = (from_resolution / 2) + to_resolution;
5955 
5956 	      p_src = myp2;
5957 	      p_dst = myp2 + desp;
5958 
5959 	      /* f938 */
5960 	      val7 = data_lsb_get (p_src, channel_size);
5961 
5962 	      if (to_width > 0)
5963 		{
5964 		  for (mywidth = 0; mywidth < to_width; mywidth++)
5965 		    {
5966 		      if (rescount >= to_resolution)
5967 			{
5968 			  rescount -= to_resolution;
5969 			  val6 = val7;
5970 			  pos++;
5971 			  if (pos < from_width)
5972 			    {
5973 			      p_src += (channels * channel_size);
5974 			      val7 = data_lsb_get (p_src, channel_size);
5975 			    }
5976 			}
5977 
5978 		      /*f9a5 */
5979 		      data_lsb_set (p_dst,
5980 				    ((((to_resolution - rescount) * val6) +
5981 				      (val7 * rescount)) / to_resolution),
5982 				    channel_size);
5983 		      rescount += from_resolution;
5984 		      p_dst += (channels * channel_size);
5985 		    }
5986 		}
5987 
5988 	      myp2 += channel_size;
5989 	    }
5990 
5991 	  rst = OK;
5992 	}
5993       else
5994 	rst = OK;
5995     }
5996   else
5997     {
5998       /* RSZ_LINEART mode */
5999       /* fa02 */
6000       /*
6001          to_buffer = FAC8 = 0x2353f0
6002          to_resolution      = FACC = 0x4b
6003          to_width    = FAD0 = 0x352
6004          from_buffer = FAD4 = 0x234650
6005          from_resolution      = FAD8 = 0x64
6006          from_width    = FADC = 0x46d
6007          myresize_mode   = FAE0 = 1
6008        */
6009       SANE_Int myres2;		/* fac8 */
6010       SANE_Int sres;
6011       SANE_Int lfae0;
6012       SANE_Int lfad8;
6013       SANE_Int myres;
6014       SANE_Int cont = 1;
6015       SANE_Int someval;
6016       SANE_Int bit;		/*lfaa8 */
6017 
6018       myres2 = from_resolution;
6019       sres = (myres2 / 2) + to_resolution;
6020       value = _B0 (*from_buffer);
6021       bit = 0;
6022       lfae0 = 0;
6023       lfad8 = value >> 7;
6024       someval = lfad8;
6025       *to_buffer = 0;
6026 
6027       if (to_width > 0)
6028 	{
6029 	  myres = to_resolution;
6030 	  to_resolution = myres / 2;
6031 	  do
6032 	    {
6033 	      if (sres >= myres)
6034 		{
6035 		  sres -= myres;
6036 		  lfae0++;
6037 		  cont++;
6038 		  lfad8 = someval;
6039 		  if (lfae0 < from_width)
6040 		    {
6041 		      if (cont == 8)
6042 			{
6043 			  cont = 0;
6044 			  from_buffer++;
6045 			}
6046 		      bit = (((0x80 >> cont) & *from_buffer) != 0) ? 1 : 0;
6047 		    }
6048 		}
6049 	      /*faa6 */
6050 	      if ((((myres - sres) * lfad8) + (bit * sres)) > to_resolution)
6051 		*to_buffer |= (0x80 >> bit);
6052 
6053 	      bit++;
6054 	      if (bit == 8)
6055 		{
6056 		  bit = 0;
6057 		  to_buffer++;
6058 		  *to_buffer = 0;
6059 		}
6060 	      to_width--;
6061 	      sres += myres2;
6062 	    }
6063 	  while (to_width > 0);
6064 	  rst = OK;
6065 	}
6066     }
6067 
6068   DBG (DBG_FNC, "- Resize_Increase: %i\n", rst);
6069 
6070   return rst;
6071 }
6072 
6073 static SANE_Int
Resize_Start(struct st_device * dev,SANE_Int * transferred)6074 Resize_Start (struct st_device *dev, SANE_Int * transferred)
6075 {
6076   SANE_Int rst = ERROR;
6077   struct st_resize *rz = dev->Resize;
6078 
6079   DBG (DBG_FNC, "+ Resize_Start(*transferred):\n");
6080 
6081   if (Resize_CreateBuffers
6082       (dev, line_size, rz->bytesperline, rz->bytesperline) == ERROR)
6083     return ERROR;
6084 
6085   if (arrangeline2 == FIX_BY_SOFT)
6086     {
6087       /* fee0 */
6088       if (scan2.colormode == CM_COLOR)
6089 	rst = Arrange_Colour (dev, rz->v3624, line_size, transferred);
6090       else
6091 	rst = Arrange_NonColour (dev, rz->v3624, line_size, transferred);
6092     }
6093   else
6094     rst = Read_Block (dev, line_size, rz->v3624, transferred);	/* ff03 */
6095 
6096   /* Redimensionado */
6097   switch (rz->type)
6098     {
6099     case RSZ_DECREASE:
6100       /* ff1b */
6101       Resize_Decrease (rz->v3628, rz->resolution_x, rz->towidth, rz->v3624,
6102 		       scan2.resolution_x, rz->fromwidth, rz->mode);
6103       break;
6104     case RSZ_INCREASE:
6105       /* ff69 */
6106       rz->rescount = 0;
6107       Resize_Increase (rz->v3628, rz->resolution_x, rz->towidth, rz->v3624,
6108 		       scan2.resolution_x, rz->fromwidth, rz->mode);
6109       if (arrangeline2 == FIX_BY_SOFT)
6110 	{
6111 	  /* ffb1 */
6112 	  if (scan2.colormode == CM_COLOR)
6113 	    rst = Arrange_Colour (dev, rz->v3624, line_size, transferred);
6114 	  else
6115 	    rst = Arrange_NonColour (dev, rz->v3624, line_size, transferred);
6116 	}
6117       else
6118 	rst = Read_Block (dev, line_size, rz->v3624, transferred);	/* ffe0 */
6119 
6120       /* fff2 */
6121       Resize_Increase (rz->v362c, rz->resolution_x, rz->towidth, rz->v3624,
6122 		       scan2.resolution_x, rz->fromwidth, rz->mode);
6123       break;
6124     }
6125 
6126   /* 002a */
6127 
6128   DBG (DBG_FNC, "- Resize_Start(*transferred=%i): %i\n", *transferred, rst);
6129 
6130   return rst;
6131 }
6132 
6133 static SANE_Int
Resize_CreateBuffers(struct st_device * dev,SANE_Int size1,SANE_Int size2,SANE_Int size3)6134 Resize_CreateBuffers (struct st_device *dev, SANE_Int size1, SANE_Int size2,
6135 		      SANE_Int size3)
6136 {
6137   SANE_Int rst = ERROR;
6138   struct st_resize *rz = dev->Resize;
6139 
6140   rz->v3624 = (SANE_Byte *) malloc ((size1 + 0x40) * sizeof (SANE_Byte));
6141   rz->v3628 = (SANE_Byte *) malloc ((size2 + 0x40) * sizeof (SANE_Byte));
6142   rz->v362c = (SANE_Byte *) malloc ((size3 + 0x40) * sizeof (SANE_Byte));
6143 
6144   if ((rz->v3624 == NULL) || (rz->v3628 == NULL) || (rz->v362c == NULL))
6145     Resize_DestroyBuffers (dev);
6146   else
6147     rst = OK;
6148 
6149   DBG (DBG_FNC, "> Resize_CreateBuffers(size1=%i, size2=%i, size3=%i): %i\n",
6150        size1, size2, size3, rst);
6151 
6152   return rst;
6153 }
6154 
6155 static SANE_Int
Resize_DestroyBuffers(struct st_device * dev)6156 Resize_DestroyBuffers (struct st_device *dev)
6157 {
6158   struct st_resize *rz = dev->Resize;
6159 
6160   if (rz->v3624 != NULL)
6161     free (rz->v3624);
6162 
6163   if (rz->v3628 != NULL)
6164     free (rz->v3628);
6165 
6166   if (rz->v362c != NULL)
6167     free (rz->v362c);
6168 
6169   rz->v3624 = NULL;
6170   rz->v3628 = NULL;
6171   rz->v362c = NULL;
6172 
6173   return OK;
6174 }
6175 
6176 static SANE_Int
Reading_DestroyBuffers(struct st_device * dev)6177 Reading_DestroyBuffers (struct st_device *dev)
6178 {
6179   DBG (DBG_FNC, "> Reading_DestroyBuffers():\n");
6180 
6181   if (dev->Reading->DMABuffer != NULL)
6182     free (dev->Reading->DMABuffer);
6183 
6184   if (dev->scanning->imagebuffer != NULL)
6185     {
6186       free (dev->scanning->imagebuffer);
6187       dev->scanning->imagebuffer = NULL;
6188     }
6189 
6190   memset (dev->Reading, 0, sizeof (struct st_readimage));
6191 
6192   return OK;
6193 }
6194 
6195 static SANE_Int
Gamma_SendTables(struct st_device * dev,SANE_Byte * Regs,SANE_Byte * gammatable,SANE_Int size)6196 Gamma_SendTables (struct st_device *dev, SANE_Byte * Regs,
6197 		  SANE_Byte * gammatable, SANE_Int size)
6198 {
6199   SANE_Int rst = ERROR;
6200 
6201   DBG (DBG_FNC, "+ Gamma_SendTables(*Regs, *gammatable, size=%i):\n", size);
6202 
6203   if ((gammatable != NULL) && (size > 0))
6204     {
6205       SANE_Int transferred;
6206       SANE_Int first_table;
6207       SANE_Int cont = 0;
6208       SANE_Int retry = TRUE;
6209       SANE_Byte *mybuffer;
6210 
6211       /* lock */
6212       SetLock (dev->usb_handle, Regs, TRUE);
6213 
6214       first_table = (data_lsb_get (&Regs[0x1b4], 2) & 0x3fff) >> 4;
6215 
6216       mybuffer = (SANE_Byte *) malloc (sizeof (SANE_Byte) * size);
6217       if (mybuffer != NULL)
6218 	{
6219 	  /* Try to send buffer during 10 seconds */
6220 	  long tick = GetTickCount () + 10000;
6221 	  while ((retry == TRUE) && (tick > GetTickCount ()))
6222 	    {
6223 	      retry = FALSE;
6224 
6225 	      /* Operation type 0x14 */
6226 	      if (IWrite_Word (dev->usb_handle, 0x0000, 0x0014, 0x0800) == OK)
6227 		{
6228 		  /* Send size to write */
6229 		  if (RTS_DMA_Enable_Write (dev, 0x0000, size, first_table) ==
6230 		      OK)
6231 		    {
6232 		      /* Send data */
6233 		      if (Bulk_Operation
6234 			  (dev, BLK_WRITE, size, gammatable,
6235 			   &transferred) == OK)
6236 			{
6237 			  /* Send size to read */
6238 			  if (RTS_DMA_Enable_Read
6239 			      (dev, 0x0000, size, first_table) == OK)
6240 			    {
6241 			      /* Retrieve data */
6242 			      if (Bulk_Operation
6243 				  (dev, BLK_READ, size, mybuffer,
6244 				   &transferred) == OK)
6245 				{
6246 				  /* Check data */
6247 				  while ((cont < size) && (retry == FALSE))
6248 				    {
6249 				      if (mybuffer[cont] != gammatable[cont])
6250 					retry = TRUE;
6251 				      cont++;
6252 				    }
6253 
6254 				  if (retry == FALSE)
6255 				    rst = OK;
6256 				}
6257 			    }
6258 			}
6259 		    }
6260 		}
6261 	    }
6262 
6263 	  free (mybuffer);
6264 	}
6265 
6266       /* unlock */
6267       SetLock (dev->usb_handle, Regs, FALSE);
6268     }
6269 
6270   DBG (DBG_FNC, "- Gamma_SendTables: %i\n", rst);
6271 
6272   return rst;
6273 }
6274 
6275 static SANE_Int
Gamma_GetTables(struct st_device * dev,SANE_Byte * Gamma_buffer)6276 Gamma_GetTables (struct st_device *dev, SANE_Byte * Gamma_buffer)
6277 {
6278   SANE_Int rst = ERROR;
6279 
6280   DBG (DBG_FNC, "+ Gamma_GetTables(SANE_Byte *Gamma_buffer):\n");
6281 
6282   if (Gamma_buffer == NULL)
6283     return ERROR;
6284 
6285   /* Operation type 0x14 */
6286   if (IWrite_Word (dev->usb_handle, 0x0000, 0x0014, 0x0800) == 0x00)
6287     {
6288       SANE_Int size = 768;
6289 
6290       if (RTS_DMA_Enable_Read (dev, 0x0000, size, 0) == OK)
6291 	{
6292 	  SANE_Int transferred = 0;
6293 	  usleep (1000 * 500);
6294 
6295 	  /* Read buffer */
6296 	  rst =
6297 	    Bulk_Operation (dev, BLK_READ, size, Gamma_buffer, &transferred);
6298 	}
6299     }
6300 
6301   DBG (DBG_FNC, "- Gamma_GetTables: %i\n", rst);
6302 
6303   return rst;
6304 }
6305 
6306 static void
Gamma_FreeTables()6307 Gamma_FreeTables ()
6308 {
6309   SANE_Int c;
6310 
6311   DBG (DBG_FNC, "> Gamma_FreeTables()\n");
6312 
6313   for (c = 0; c < 3; c++)
6314     {
6315       if (hp_gamma->table[c] != NULL)
6316 	{
6317 	  free (hp_gamma->table[c]);
6318 	  hp_gamma->table[c] = NULL;
6319 	}
6320     }
6321   use_gamma_tables = FALSE;
6322 }
6323 
6324 static void
RTS_Scanner_StopScan(struct st_device * dev,SANE_Int wait)6325 RTS_Scanner_StopScan (struct st_device *dev, SANE_Int wait)
6326 {
6327   SANE_Byte data;
6328 
6329   DBG (DBG_FNC, "+ RTS_Scanner_StopScan():\n");
6330 
6331   data = 0;
6332 
6333   Reading_DestroyBuffers (dev);
6334   Resize_DestroyBuffers (dev);
6335 
6336   RTS_DMA_Reset (dev);
6337 
6338   data_bitset (&dev->init_regs[0x60b], 0x10, 0);
6339   data_bitset (&dev->init_regs[0x60a], 0x40, 0);
6340 
6341   if (Write_Buffer (dev->usb_handle, 0xee0a, &dev->init_regs[0x60a], 2) == OK)
6342     Motor_Change (dev, dev->init_regs, 3);
6343 
6344   usleep (1000 * 200);
6345 
6346   if (wait == FALSE)
6347     {
6348       Read_Byte (dev->usb_handle, 0xe801, &data);
6349       if ((data & 0x02) == 0)
6350 	{
6351 	  if (Head_IsAtHome (dev, dev->init_regs) == FALSE)
6352 	    {
6353 	      /* clear execution bit */
6354 	      data_bitset (&dev->init_regs[0x00], 0x80, 0);
6355 
6356 	      Write_Byte (dev->usb_handle, 0x00, dev->init_regs[0x00]);
6357 	      Head_ParkHome (dev, TRUE, dev->motorcfg->parkhomemotormove);
6358 	    }
6359 	}
6360     }
6361   else
6362     {
6363       /*66a1 */
6364       /* clear execution bit */
6365       data_bitset (&dev->init_regs[0x00], 0x80, 0);
6366 
6367       Write_Byte (dev->usb_handle, 0x00, dev->init_regs[0x00]);
6368       if (Head_IsAtHome (dev, dev->init_regs) == FALSE)
6369 	Head_ParkHome (dev, TRUE, dev->motorcfg->parkhomemotormove);
6370     }
6371 
6372   /*66e0 */
6373   RTS_Enable_CCD (dev, dev->init_regs, 0);
6374 
6375   Lamp_Status_Timer_Set (dev, 13);
6376 
6377   DBG (DBG_FNC, "- RTS_Scanner_StopScan()\n");
6378 }
6379 
6380 static SANE_Int
Reading_CreateBuffers(struct st_device * dev)6381 Reading_CreateBuffers (struct st_device *dev)
6382 {
6383   SANE_Byte data;
6384   SANE_Int mybytesperline;
6385   SANE_Int mybuffersize, a, b;
6386 
6387   DBG (DBG_FNC, "+ Reading_CreateBuffers():\n");
6388 
6389   data = 0;
6390 
6391   /* Gets BinarythresholdH */
6392   if (Read_Byte (dev->usb_handle, 0xe9a1, &data) == OK)
6393     binarythresholdh = data;
6394 
6395   mybytesperline =
6396     (scan2.depth == 12) ? (bytesperline * 3) / 4 : bytesperline;
6397 
6398   dev->Reading->Max_Size = 0xfc00;
6399   dev->Reading->DMAAmount = 0;
6400 
6401   a = (RTS_Debug->dmabuffersize / 63);
6402   b = (((RTS_Debug->dmabuffersize - a) / 2) + a) >> 0x0f;
6403   mybuffersize = ((b << 6) - b) << 10;
6404   if (mybuffersize < 0x1f800)
6405     mybuffersize = 0x1f800;
6406 
6407   dev->Reading->DMABufferSize = mybuffersize;	/*3FFC00 4193280 */
6408 
6409   do
6410     {
6411       dev->Reading->DMABuffer =
6412 	(SANE_Byte *) malloc (dev->Reading->DMABufferSize *
6413 			      sizeof (SANE_Byte));
6414       if (dev->Reading->DMABuffer != NULL)
6415 	break;
6416       dev->Reading->DMABufferSize -= dev->Reading->Max_Size;
6417     }
6418   while (dev->Reading->DMABufferSize >= dev->Reading->Max_Size);
6419 
6420   /* 6003 */
6421   dev->Reading->Starting = TRUE;
6422 
6423   dev->Reading->Size4Lines = (mybytesperline > dev->Reading->Max_Size) ?
6424     mybytesperline : (dev->Reading->Max_Size / mybytesperline) *
6425     mybytesperline;
6426 
6427   dev->Reading->ImageSize = imagesize;
6428   read_v15b4 = v15b4;
6429 
6430   DBG (DBG_FNC, "- Reading_CreateBuffers():\n");
6431 
6432   return OK;
6433 }
6434 
6435 static SANE_Int
RTS_ScanCounter_Inc(struct st_device * dev)6436 RTS_ScanCounter_Inc (struct st_device *dev)
6437 {
6438   /* Keep a count of the number of scans done by this scanner */
6439 
6440   SANE_Int idata;
6441 
6442   DBG (DBG_FNC, "+ RTS_ScanCounter_Inc():\n");
6443 
6444   /* check if chipset supports accessing eeprom */
6445   if ((dev->chipset->capabilities & CAP_EEPROM) != 0)
6446     {
6447       SANE_Byte cdata = 0;
6448       SANE_Byte somebuffer[26];
6449 
6450       switch (dev->chipset->model)
6451 	{
6452 	case RTS8822L_02A:
6453 	case RTS8822BL_03A:
6454 	  /* value is 4 bytes size starting from address 0x21 in msb format */
6455 	  if (RTS_EEPROM_ReadInteger (dev->usb_handle, 0x21, &idata) == OK)
6456 	    {
6457 	      idata = data_swap_endianess (idata, 4) + 1;
6458 	      idata = data_swap_endianess (idata, 4);
6459 	      RTS_EEPROM_WriteInteger (dev->usb_handle, 0x21, idata);
6460 	    }
6461 	  break;
6462 	default:
6463 	  /* value is 4 bytes size starting from address 0x21 in lsb format */
6464 	  memset (&somebuffer, 0, sizeof (somebuffer));
6465 	  somebuffer[4] = 0x0c;
6466 
6467 	  RTS_EEPROM_ReadInteger (dev->usb_handle, 0x21, &idata);
6468 	  data_lsb_set (&somebuffer[0], idata + 1, 4);
6469 
6470 	  RTS_EEPROM_ReadByte (dev->usb_handle, 0x003a, &cdata);
6471 	  somebuffer[25] = cdata;
6472 	  RTS_EEPROM_WriteBuffer (dev->usb_handle, 0x21, somebuffer, 0x1a);
6473 	  break;
6474 	}
6475     }
6476 
6477   DBG (DBG_FNC, "- RTS_ScanCounter_Inc()\n");
6478 
6479   return OK;
6480 }
6481 
6482 static SANE_Int
RTS_ScanCounter_Get(struct st_device * dev)6483 RTS_ScanCounter_Get (struct st_device *dev)
6484 {
6485   /* Returns the number of scans done by this scanner */
6486 
6487   SANE_Int idata = 0;
6488 
6489   DBG (DBG_FNC, "+ RTS_ScanCounter_Get():\n");
6490 
6491   /* check if chipset supports accessing eeprom */
6492   if ((dev->chipset->capabilities & CAP_EEPROM) != 0)
6493     {
6494       RTS_EEPROM_ReadInteger (dev->usb_handle, 0x21, &idata);
6495 
6496       switch (dev->chipset->model)
6497 	{
6498 	case RTS8822L_02A:
6499 	case RTS8822BL_03A:
6500 	  /* value is 4 bytes size starting from address 0x21 in msb format */
6501 	  idata = data_swap_endianess (idata, 4);
6502 	  break;
6503 	default:		/* RTS8822L_01H */
6504 	  /* value is 4 bytes size starting from address 0x21 in lsb format */
6505 	  idata &= 0xffffffff;
6506 	  break;
6507 	}
6508     }
6509 
6510   DBG (DBG_FNC, "- RTS_ScanCounter_Get(): %i\n", idata);
6511 
6512   return idata;
6513 }
6514 
6515 static SANE_Int
Read_Image(struct st_device * dev,SANE_Int buffer_size,SANE_Byte * buffer,SANE_Int * transferred)6516 Read_Image (struct st_device *dev, SANE_Int buffer_size, SANE_Byte * buffer,
6517 	    SANE_Int * transferred)
6518 {
6519   SANE_Int rst;
6520   SANE_Byte mycolormode;
6521 
6522   DBG (DBG_FNC, "+ Read_Image(buffer_size=%i, *buffer, *transferred):\n",
6523        buffer_size);
6524 
6525   *transferred = 0;
6526   mycolormode = scan2.colormode;
6527   rst = ERROR;
6528   if ((scan2.colormode != CM_COLOR) && (scan2.channel == 3))
6529     mycolormode = 3;
6530 
6531   if (dev->Resize->type == RSZ_NONE)
6532     {
6533       if (arrangeline == FIX_BY_SOFT)
6534 	{
6535 	  switch (mycolormode)
6536 	    {
6537 	    case CM_COLOR:
6538 	      rst = Arrange_Colour (dev, buffer, buffer_size, transferred);
6539 	      break;
6540 	    case 3:
6541 	      rst = Arrange_Compose (dev, buffer, buffer_size, transferred);
6542 	      break;
6543 	    default:
6544 	      rst = Arrange_NonColour (dev, buffer, buffer_size, transferred);
6545 	      break;
6546 	    }
6547 	}
6548       else
6549 	rst = Read_Block (dev, buffer_size, buffer, transferred);	/*00fe */
6550     }
6551   else
6552     rst = Read_ResizeBlock (dev, buffer, buffer_size, transferred);	/*010d */
6553 
6554   DBG (DBG_FNC, "- Read_Image(*transferred=%i): %i\n", *transferred, rst);
6555 
6556   return rst;
6557 }
6558 
6559 static SANE_Int
Arrange_Compose(struct st_device * dev,SANE_Byte * buffer,SANE_Int buffer_size,SANE_Int * transferred)6560 Arrange_Compose (struct st_device *dev, SANE_Byte * buffer,
6561 		 SANE_Int buffer_size, SANE_Int * transferred)
6562 {
6563   /*
6564      fnb250
6565 
6566      0600FA7C   05E10048 buffer
6567      0600FA80   0000F906 buffer_size
6568    */
6569   SANE_Byte *mybuffer = buffer;	/* fa7c */
6570   SANE_Int mydistance;		/*ebp */
6571   SANE_Int mydots;		/*fa74 */
6572   SANE_Int channel_size;
6573   SANE_Int c;
6574   struct st_scanning *scn;
6575 
6576   /*mywidth = fa70 */
6577 
6578   DBG (DBG_FNC, "+ Arrange_Compose(*buffer, buffer_size=%i, *transferred):\n",
6579        buffer_size);
6580 
6581   channel_size = (scan2.depth == 8) ? 1 : 2;
6582 
6583   /* this is just to make code more legible */
6584   scn = dev->scanning;
6585 
6586   if (scn->imagebuffer == NULL)
6587     {
6588       if (dev->sensorcfg->type == CCD_SENSOR)
6589 	mydistance =
6590 	  (dev->sensorcfg->line_distance * scan2.resolution_y) /
6591 	  dev->sensorcfg->resolution;
6592       else
6593 	mydistance = 0;
6594 
6595       if (mydistance != 0)
6596 	{
6597 	  scn->bfsize =
6598 	    (scn->arrange_hres ==
6599 	     TRUE) ? scn->arrange_sensor_evenodd_dist : 0;
6600 	  scn->bfsize = line_size * (scn->bfsize + (mydistance * 2) + 1);
6601 	}
6602       else
6603 	scn->bfsize = line_size * 2;
6604 
6605       /*b2f0 */
6606       scn->imagebuffer =
6607 	(SANE_Byte *) malloc (scn->bfsize * sizeof (SANE_Byte));
6608       if (scn->imagebuffer == NULL)
6609 	return ERROR;
6610 
6611       scn->imagepointer = scn->imagebuffer;
6612       if (Read_Block (dev, scn->bfsize, scn->imagebuffer, transferred) ==
6613 	  ERROR)
6614 	return ERROR;
6615 
6616       /* Calculate channel displacements */
6617       scn->arrange_orderchannel = FALSE;
6618       for (c = CL_RED; c <= CL_BLUE; c++)
6619 	{
6620 	  if (mydistance == 0)
6621 	    {
6622 	      /*b34e */
6623 	      if (scn->arrange_hres == FALSE)
6624 		{
6625 		  if ((((dev->sensorcfg->line_distance * scan2.resolution_y) *
6626 			2) / dev->sensorcfg->resolution) == 1)
6627 		    scn->arrange_orderchannel = TRUE;
6628 
6629 		  if (scn->arrange_orderchannel == TRUE)
6630 		    scn->desp[c] =
6631 		      ((dev->sensorcfg->rgb_order[c] / 2) * line_size) +
6632 		      (channel_size * c);
6633 		  else
6634 		    scn->desp[c] = channel_size * c;
6635 		}
6636 	    }
6637 	  else
6638 	    {
6639 	      /*b3e3 */
6640 	      scn->desp[c] =
6641 		(dev->sensorcfg->rgb_order[c] * (mydistance * line_size)) +
6642 		(channel_size * c);
6643 
6644 	      if (scn->arrange_hres == TRUE)
6645 		{
6646 		  /*b43b */
6647 		  scn->desp1[c] = scn->desp[c];
6648 		  scn->desp2[c] =
6649 		    ((channel_size * 3) + scn->desp1[c]) +
6650 		    (scn->arrange_sensor_evenodd_dist * line_size);
6651 		};
6652 	    }
6653 	}
6654 
6655       for (c = CL_RED; c <= CL_BLUE; c++)
6656 	{
6657 	  if (scn->arrange_hres == TRUE)
6658 	    {
6659 	      scn->pColour2[c] = scn->imagebuffer + scn->desp2[c];
6660 	      scn->pColour1[c] = scn->imagebuffer + scn->desp1[c];
6661 	    }
6662 	  else
6663 	    scn->pColour[c] = scn->imagebuffer + scn->desp[c];
6664 	}
6665     }
6666 
6667   /*b545 */
6668   buffer_size /= line_size;
6669   mydots = line_size / (channel_size * 3);
6670 
6671   while (buffer_size > 0)
6672     {
6673       if (scn->arrange_orderchannel == FALSE)
6674 	{
6675 	  /*b5aa */
6676 	  if (scn->arrange_hres == TRUE)
6677 	    Triplet_Compose_HRes (scn->pColour1[CL_RED],
6678 				  scn->pColour1[CL_GREEN],
6679 				  scn->pColour1[CL_BLUE],
6680 				  scn->pColour2[CL_RED],
6681 				  scn->pColour2[CL_GREEN],
6682 				  scn->pColour2[CL_BLUE], mybuffer, mydots);
6683 	  else
6684 	    Triplet_Compose_LRes (scn->pColour[CL_RED],
6685 				  scn->pColour[CL_GREEN],
6686 				  scn->pColour[CL_BLUE], mybuffer, mydots);
6687 	}
6688       else
6689 	Triplet_Compose_Order (dev, scn->pColour[CL_RED],
6690 			       scn->pColour[CL_GREEN], scn->pColour[CL_BLUE],
6691 			       mybuffer, mydots);
6692 
6693       /*b5f8 */
6694       mybuffer += line_size;
6695       scn->arrange_size -= bytesperline;
6696       if (scn->arrange_size < 0)
6697 	v15bc--;
6698 
6699       buffer_size--;
6700       if (buffer_size == 0)
6701 	{
6702 	  if ((scn->arrange_size | v15bc) == 0)
6703 	    return OK;
6704 	}
6705 
6706       /*b63f */
6707       if (Read_Block (dev, line_size, scn->imagepointer, transferred) ==
6708 	  ERROR)
6709 	return ERROR;
6710 
6711       for (c = CL_RED; c <= CL_BLUE; c++)
6712 	{
6713 	  if (scn->arrange_hres == TRUE)
6714 	    {
6715 	      /*b663 */
6716 	      scn->desp2[c] = (scn->desp2[c] + line_size) % scn->bfsize;
6717 	      scn->desp1[c] = (scn->desp1[c] + line_size) % scn->bfsize;
6718 
6719 	      scn->pColour2[c] = scn->imagebuffer + scn->desp2[c];
6720 	      scn->pColour1[c] = scn->imagebuffer + scn->desp1[c];
6721 	    }
6722 	  else
6723 	    {
6724 	      /*b74a */
6725 	      scn->desp[c] = (scn->desp[c] + line_size) % scn->bfsize;
6726 	      scn->pColour[c] = scn->imagebuffer + scn->desp[c];
6727 	    }
6728 	}
6729 
6730       /*b7be */
6731       scn->imagepointer += line_size;
6732       if (scn->imagepointer >= (scn->imagebuffer + scn->bfsize))
6733 	scn->imagepointer = scn->imagebuffer;
6734     }
6735 
6736   return OK;
6737 }
6738 
6739 static void
Triplet_Compose_HRes(SANE_Byte * pRed1,SANE_Byte * pGreen1,SANE_Byte * pBlue1,SANE_Byte * pRed2,SANE_Byte * pGreen2,SANE_Byte * pBlue2,SANE_Byte * buffer,SANE_Int Width)6740 Triplet_Compose_HRes (SANE_Byte * pRed1, SANE_Byte * pGreen1,
6741 		      SANE_Byte * pBlue1, SANE_Byte * pRed2,
6742 		      SANE_Byte * pGreen2, SANE_Byte * pBlue2,
6743 		      SANE_Byte * buffer, SANE_Int Width)
6744 {
6745   SANE_Int Value;
6746   SANE_Int Channel_size;
6747   SANE_Int max_value;
6748 
6749   DBG (DBG_FNC,
6750        "> Triplet_Compose_HRes(*pRed1, *pGreen1, *pBlue1, *pRed2 *pGreen2, *pBlue2, *buffer, Width=%i):\n",
6751        Width);
6752 
6753   Width /= 2;
6754   Channel_size = (scan2.depth > 8) ? 2 : 1;
6755   max_value = (1 << scan2.depth) - 1;
6756 
6757   while (Width > 0)
6758     {
6759       Value =
6760 	data_lsb_get (pRed1, Channel_size) + data_lsb_get (pGreen1,
6761 							   Channel_size) +
6762 	data_lsb_get (pBlue1, Channel_size);
6763 
6764       Value = min (Value, max_value);
6765 
6766       if (v1600 != NULL)
6767 	{
6768 	  if (scan2.depth > 8)
6769 	    Value = *(v1600 + (Value >> 8)) | _B0 (Value);
6770 	  else
6771 	    Value = *(v1600 + Value);
6772 	}
6773 
6774       data_lsb_set (buffer, Value, Channel_size);
6775       buffer += Channel_size;
6776 
6777       Value =
6778 	data_lsb_get (pRed2, Channel_size) + data_lsb_get (pGreen2,
6779 							   Channel_size) +
6780 	data_lsb_get (pBlue2, Channel_size);
6781 
6782       Value = min (Value, max_value);
6783 
6784       if (v1600 != NULL)
6785 	{
6786 	  if (scan2.depth > 8)
6787 	    Value = *(v1600 + (Value >> 8)) | _B0 (Value);
6788 	  else
6789 	    Value = *(v1600 + Value);
6790 	}
6791 
6792       data_lsb_set (buffer, Value, Channel_size);
6793       buffer += Channel_size;
6794 
6795       pRed1 += 6 * Channel_size;
6796       pGreen1 += 6 * Channel_size;
6797       pBlue1 += 6 * Channel_size;
6798 
6799       pRed2 += 6 * Channel_size;
6800       pGreen2 += 6 * Channel_size;
6801       pBlue2 += 6 * Channel_size;
6802 
6803       Width--;
6804     }
6805 }
6806 
6807 static void
Triplet_Compose_Order(struct st_device * dev,SANE_Byte * pRed,SANE_Byte * pGreen,SANE_Byte * pBlue,SANE_Byte * buffer,SANE_Int dots)6808 Triplet_Compose_Order (struct st_device *dev, SANE_Byte * pRed,
6809 		       SANE_Byte * pGreen, SANE_Byte * pBlue,
6810 		       SANE_Byte * buffer, SANE_Int dots)
6811 {
6812   SANE_Int Value;
6813 
6814   DBG (DBG_FNC,
6815        "> Triplet_Compose_Order(*pRed, *pGreen, *pBlue, *buffer, dots=%i):\n",
6816        dots);
6817 
6818   if (scan2.depth > 8)
6819     {
6820       /* c0fe */
6821       dots = dots / 2;
6822       while (dots > 0)
6823 	{
6824 	  Value =
6825 	    min (data_lsb_get (pRed, 2) + data_lsb_get (pGreen, 2) +
6826 		 data_lsb_get (pBlue, 2), 0xffff);
6827 
6828 	  if (v1600 != NULL)
6829 	    Value = (*(v1600 + (Value >> 8)) << 8) | _B0 (Value);
6830 
6831 	  data_lsb_set (buffer, Value, 2);
6832 
6833 	  buffer += 2;
6834 	  pRed += 6;
6835 	  pGreen += 6;
6836 	  pBlue += 6;
6837 	  dots--;
6838 	}
6839     }
6840   else
6841     {
6842       SANE_Byte *myp1, *myp2, *myp3;
6843 
6844       if (dev->sensorcfg->rgb_order[CL_RED] == 1)
6845 	{
6846 	  myp1 = pRed;
6847 	  myp2 = pGreen;
6848 	  myp3 = pBlue;
6849 	}
6850       else if (dev->sensorcfg->rgb_order[CL_GREEN] == 1)
6851 	{
6852 	  myp1 = pGreen;
6853 	  myp2 = pRed;
6854 	  myp3 = pBlue;
6855 	}
6856       else
6857 	{
6858 	  myp1 = pBlue;
6859 	  myp2 = pRed;
6860 	  myp3 = pGreen;
6861 	}
6862 
6863       while (dots > 0)
6864 	{
6865 	  Value =
6866 	    min (((*myp1 + *(line_size + myp1)) / 2) + *myp2 + *myp3, 0xff);
6867 
6868 	  *buffer = (v1600 == NULL) ? _B0 (Value) : *(v1600 + Value);
6869 
6870 	  buffer++;
6871 	  myp1 += 3;
6872 	  myp2 += 3;
6873 	  myp3 += 3;
6874 	  dots--;
6875 	}
6876     }
6877 }
6878 
6879 static void
Triplet_Compose_LRes(SANE_Byte * pRed,SANE_Byte * pGreen,SANE_Byte * pBlue,SANE_Byte * buffer,SANE_Int dots)6880 Triplet_Compose_LRes (SANE_Byte * pRed, SANE_Byte * pGreen, SANE_Byte * pBlue,
6881 		      SANE_Byte * buffer, SANE_Int dots)
6882 {
6883   SANE_Int Value;
6884   SANE_Int Channel_size;
6885   SANE_Int max_value;
6886 
6887   DBG (DBG_FNC,
6888        "> Triplet_Compose_LRes(*pRed, *pGreen, *pBlue, *buffer, dots=%i):\n",
6889        dots);
6890 
6891   Channel_size = (scan2.depth > 8) ? 2 : 1;
6892   max_value = (1 << scan2.depth) - 1;
6893 
6894   /*bf59 */
6895   while (dots > 0)
6896     {
6897       Value =
6898 	data_lsb_get (pRed, Channel_size) + data_lsb_get (pGreen,
6899 							  Channel_size) +
6900 	data_lsb_get (pBlue, Channel_size);
6901 
6902       Value = min (Value, max_value);
6903 
6904       if (v1600 != NULL)
6905 	{
6906 	  if (scan2.depth > 8)
6907 	    Value = (*(v1600 + (Value >> 8)) << 8) | _B0 (Value);
6908 	  else
6909 	    Value = _B0 (*(v1600 + Value));
6910 	}
6911 
6912       data_lsb_set (buffer, Value, Channel_size);
6913 
6914       buffer += Channel_size;
6915       pRed += Channel_size * 3;
6916       pGreen += Channel_size * 3;
6917       pBlue += Channel_size * 3;
6918       dots--;
6919     }
6920 }
6921 
6922 static void
Triplet_Colour_Order(struct st_device * dev,SANE_Byte * pRed,SANE_Byte * pGreen,SANE_Byte * pBlue,SANE_Byte * buffer,SANE_Int Width)6923 Triplet_Colour_Order (struct st_device *dev, SANE_Byte * pRed,
6924 		      SANE_Byte * pGreen, SANE_Byte * pBlue,
6925 		      SANE_Byte * buffer, SANE_Int Width)
6926 {
6927   SANE_Int Value;
6928 
6929   DBG (DBG_FNC,
6930        "> Triplet_Colour_Order(*pRed, *pGreen, *pBlue, *buffer, Width=%i):\n",
6931        Width);
6932 
6933   if (scan2.depth > 8)
6934     {
6935       Width = Width / 2;
6936       while (Width > 0)
6937 	{
6938 	  Value = data_lsb_get (pRed, 2);
6939 	  data_lsb_set (buffer, Value, 2);
6940 
6941 	  Value = data_lsb_get (pGreen, 2);
6942 	  data_lsb_set (buffer + 2, Value, 2);
6943 
6944 	  Value = data_lsb_get (pBlue, 2);
6945 	  data_lsb_set (buffer + 4, Value, 2);
6946 
6947 	  pRed += 6;
6948 	  pGreen += 6;
6949 	  pBlue += 6;
6950 	  buffer += 6;
6951 	  Width--;
6952 	}
6953     }
6954   else
6955     {
6956       SANE_Int Colour;
6957 
6958       if (dev->sensorcfg->rgb_order[CL_RED] == 1)
6959 	Colour = CL_RED;
6960       else if (dev->sensorcfg->rgb_order[CL_GREEN] == 1)
6961 	Colour = CL_GREEN;
6962       else
6963 	Colour = CL_BLUE;
6964 
6965       while (Width > 0)
6966 	{
6967 	  switch (Colour)
6968 	    {
6969 	    case CL_RED:
6970 	      *buffer = (*pRed + *(pRed + line_size)) / 2;
6971 	      *(buffer + 1) = *pGreen;
6972 	      *(buffer + 2) = *pBlue;
6973 	      break;
6974 	    case CL_GREEN:
6975 	      *buffer = *pRed;
6976 	      *(buffer + 1) = ((*pGreen + *(pGreen + line_size)) / 2);
6977 	      *(buffer + 2) = *pBlue;
6978 	      break;
6979 	    case CL_BLUE:
6980 	      *buffer = *pRed;
6981 	      *(buffer + 1) = *pGreen;
6982 	      *(buffer + 2) = ((*pBlue + *(pBlue + line_size)) / 2);
6983 	      break;
6984 	    }
6985 
6986 	  pRed += 3;
6987 	  pGreen += 3;
6988 	  pBlue += 3;
6989 	  buffer += 3;
6990 
6991 	  Width--;
6992 	}
6993     }
6994 }
6995 
6996 static void
Triplet_Colour_HRes(SANE_Byte * pRed1,SANE_Byte * pGreen1,SANE_Byte * pBlue1,SANE_Byte * pRed2,SANE_Byte * pGreen2,SANE_Byte * pBlue2,SANE_Byte * buffer,SANE_Int Width)6997 Triplet_Colour_HRes (SANE_Byte * pRed1, SANE_Byte * pGreen1,
6998 		     SANE_Byte * pBlue1, SANE_Byte * pRed2,
6999 		     SANE_Byte * pGreen2, SANE_Byte * pBlue2,
7000 		     SANE_Byte * buffer, SANE_Int Width)
7001 {
7002   SANE_Int Value;
7003   SANE_Int channel_size;
7004   SANE_Int c;
7005   SANE_Byte *pPointers[6];
7006 
7007   pPointers[0] = pRed1;
7008   pPointers[1] = pGreen1;
7009   pPointers[2] = pBlue1;
7010 
7011   pPointers[3] = pRed2;
7012   pPointers[4] = pGreen2;
7013   pPointers[5] = pBlue2;
7014 
7015   DBG (DBG_FNC,
7016        "> Triplet_Colour_HRes(*pRed1, *pGreen1, *pBlue1, *pRed2, *pGreen2, *pBlue2, *buffer, Width=%i):\n",
7017        Width);
7018 
7019   channel_size = (scan2.depth > 8) ? 2 : 1;
7020 
7021   Width = Width / 2;
7022   while (Width > 0)
7023     {
7024       for (c = 0; c < 6; c++)
7025 	{
7026 	  Value = data_lsb_get (pPointers[c], channel_size);
7027 	  data_lsb_set (buffer, Value, channel_size);
7028 
7029 	  pPointers[c] += (6 * channel_size);
7030 	  buffer += (channel_size);
7031 	}
7032       Width--;
7033     }
7034 }
7035 
7036 static void
Triplet_Colour_LRes(SANE_Int Width,SANE_Byte * Buffer,SANE_Byte * pChannel1,SANE_Byte * pChannel2,SANE_Byte * pChannel3)7037 Triplet_Colour_LRes (SANE_Int Width, SANE_Byte * Buffer,
7038 		     SANE_Byte * pChannel1, SANE_Byte * pChannel2,
7039 		     SANE_Byte * pChannel3)
7040 {
7041   /*
7042      05F0FA4C   04EBAE4A  /CALL to Assumed StdFunc6 from hpgt3970.04EBAE45
7043      05F0FA50   00234FF8  |Arg1 = 00234FF8 pChannel3
7044      05F0FA54   002359EF  |Arg2 = 002359EF pChannel2
7045      05F0FA58   002363E6  |Arg3 = 002363E6 pChannel1
7046      05F0FA5C   05D10048  |Arg4 = 05D10048 Buffer
7047      05F0FA60   00000352  |Arg5 = 00000352 Width
7048    */
7049 
7050   /* Esta funcion une los tres canales de color en un triplete
7051      Inicialmente cada color está separado en 3 buffers apuntados
7052      por pChannel1 ,2 y 3
7053    */
7054   SANE_Int Value;
7055   SANE_Int channel_size;
7056   SANE_Int c;
7057   SANE_Byte *pChannels[3];
7058 
7059   pChannels[0] = pChannel3;
7060   pChannels[1] = pChannel2;
7061   pChannels[2] = pChannel1;
7062 
7063   DBG (DBG_FNC, "> Triplet_Colour_LRes(Width=%i, *Buffer2, *p1, *p2, *p3):\n",
7064        Width);
7065 
7066   channel_size = (scan2.depth > 8) ? 2 : 1;
7067   while (Width > 0)
7068     {
7069       /* ba74 */
7070       for (c = 0; c < 3; c++)
7071 	{
7072 	  Value = data_lsb_get (pChannels[c], channel_size);
7073 	  data_lsb_set (Buffer, Value, channel_size);
7074 
7075 	  pChannels[c] += channel_size;
7076 	  Buffer += channel_size;
7077 	}
7078       Width--;
7079     }
7080 }
7081 
7082 static SANE_Int
Read_ResizeBlock(struct st_device * dev,SANE_Byte * buffer,SANE_Int buffer_size,SANE_Int * transferred)7083 Read_ResizeBlock (struct st_device *dev, SANE_Byte * buffer,
7084 		  SANE_Int buffer_size, SANE_Int * transferred)
7085 {
7086   /*The Beach
7087      buffer      = FA7C   05E30048
7088      buffer_size = FA80   0000F906
7089    */
7090 
7091   SANE_Int rst = ERROR;		/* fa68 */
7092   SANE_Int lfa54;
7093   SANE_Int lfa58;
7094   SANE_Byte *pP1;		/* fa5c */
7095   SANE_Byte *pP2;		/* fa60 */
7096   SANE_Int bOk;
7097   struct st_resize *rz = dev->Resize;
7098 
7099   /* fa74 = Resize->resolution_y */
7100   /* fa70 = Resize->resolution_x */
7101   /* fa64 = scan2.resolution_y  */
7102   /* fa6c = scan2.resolution_x  */
7103 
7104   DBG (DBG_FNC,
7105        "+ Read_ResizeBlock(*buffer, buffer_size=%i, *transferred):\n",
7106        buffer_size);
7107 
7108   if (rz->type == RSZ_DECREASE)
7109     {
7110       lfa58 = 0;
7111       do
7112 	{
7113 	  bOk = 1;
7114 	  if (arrangeline2 == FIX_BY_SOFT)
7115 	    {
7116 	      if (scan2.colormode == CM_COLOR)
7117 		rst = Arrange_Colour (dev, rz->v3624, line_size, transferred);
7118 	      else
7119 		rst =
7120 		  Arrange_NonColour (dev, rz->v3624, line_size, transferred);
7121 	    }
7122 	  else
7123 	    rst = Read_Block (dev, line_size, rz->v3624, transferred);
7124 
7125 	  /*f2df */
7126 	  Resize_Decrease (rz->v362c, rz->resolution_x, rz->towidth,
7127 			   rz->v3624, scan2.resolution_x, rz->fromwidth,
7128 			   rz->mode);
7129 	  rz->rescount += rz->resolution_y;
7130 
7131 	  if (rz->rescount > scan2.resolution_y)
7132 	    {
7133 	      /*f331 */
7134 	      rz->rescount -= scan2.resolution_y;
7135 	      if (scan2.depth == 8)
7136 		{
7137 		  /* f345 */
7138 		  pP1 = rz->v3628;
7139 		  pP2 = rz->v362c;
7140 		  if (rz->mode == RSZ_LINEART)
7141 		    {
7142 		      /* f36b */
7143 		      SANE_Int bit = 0;
7144 		      SANE_Byte *pP3 = rz->v362c;
7145 		      SANE_Int value;
7146 
7147 		      *buffer = 0;
7148 		      lfa54 = 0;
7149 		      while (lfa54 < rz->towidth)
7150 			{
7151 			  if (bit == 8)
7152 			    {
7153 			      buffer++;
7154 			      *buffer = 0;
7155 			      pP1++;
7156 			      bit = 0;
7157 			      pP3++;
7158 			    }
7159 
7160 			  value =
7161 			    ((*pP1 & (0x80 >> bit)) != 0) ? rz->rescount : 0;
7162 
7163 			  if ((*pP3 & (0x80 >> bit)) != 0)
7164 			    value += (scan2.resolution_y - rz->rescount);
7165 
7166 			  if (value > rz->resolution_y)
7167 			    *buffer |= (0x80 >> bit);
7168 
7169 			  bit++;
7170 			  lfa54++;
7171 			}
7172 		    }
7173 		  else
7174 		    {
7175 		      /* f414 */
7176 		      lfa54 = 0;
7177 		      while (lfa54 < rz->bytesperline)
7178 			{
7179 			  *buffer =
7180 			    _B0 ((((scan2.resolution_y -
7181 				    rz->rescount) * *pP2) +
7182 				  (*pP1 * rz->rescount)) /
7183 				 scan2.resolution_y);
7184 			  pP1++;
7185 			  pP2++;
7186 			  buffer++;
7187 			  lfa54++;
7188 			}
7189 		    }
7190 		}
7191 	      else
7192 		{
7193 		  /* f47d */
7194 		  lfa54 = 0;
7195 		  pP1 = rz->v3628;
7196 		  pP2 = rz->v362c;
7197 
7198 		  if ((rz->bytesperline & 0xfffffffe) > 0)
7199 		    {
7200 		      SANE_Int value;
7201 		      do
7202 			{
7203 			  value =
7204 			    (((scan2.resolution_y -
7205 			       rz->rescount) * data_lsb_get (pP2,
7206 							     2)) +
7207 			     (data_lsb_get (pP1, 2) * rz->rescount)) /
7208 			    scan2.resolution_y;
7209 			  data_lsb_set (buffer, value, 2);
7210 
7211 			  buffer += 2;
7212 			  pP1 += 2;
7213 			  pP2 += 2;
7214 			  lfa54++;
7215 			}
7216 		      while (lfa54 < (rz->bytesperline / 2));
7217 		    }
7218 		}
7219 	    }
7220 	  else
7221 	    bOk = 0;
7222 	  /* f4fd f502 */
7223 	  pP1 = rz->v3628;
7224 	  /* swap pointers */
7225 	  rz->v3628 = rz->v362c;
7226 	  rz->v362c = pP1;
7227 	}
7228       while (bOk == 0);
7229     }
7230   else
7231     {
7232       /*f530 */
7233       SANE_Int lfa68;
7234       SANE_Int transferred;
7235       SANE_Int channel_size;
7236 
7237       rz->rescount += scan2.resolution_y;
7238       lfa58 = 0;
7239       if (rz->rescount > rz->resolution_y)
7240 	{
7241 	  lfa68 = 1;
7242 	  rz->rescount -= rz->resolution_y;
7243 	}
7244       else
7245 	lfa68 = 0;
7246 
7247       pP1 = rz->v3628;
7248       pP2 = rz->v362c;
7249 
7250       if (rz->mode == RSZ_LINEART)
7251 	{
7252 	  /*f592 */
7253 	  *buffer = 0;
7254 
7255 	  if (rz->towidth > 0)
7256 	    {
7257 	      SANE_Int mask, mres;
7258 	      /* lfa60 = rz->resolution_y     */
7259 	      /* lfa7c = rz->resolution_y / 2 */
7260 
7261 	      for (lfa54 = 0; lfa54 < rz->towidth; lfa54++)
7262 		{
7263 		  mask = 0x80 >> lfa58;
7264 
7265 		  mres = ((mask & *pP1) != 0) ? rz->rescount : 0;
7266 
7267 		  if ((mask & *pP2) != 0)
7268 		    mres += (rz->resolution_y - rz->rescount);
7269 
7270 		  if (mres > (rz->resolution_y / 2))
7271 		    *buffer = *buffer | mask;
7272 
7273 		  lfa58++;
7274 		  if (lfa58 == 8)
7275 		    {
7276 		      lfa58 = 0;
7277 		      buffer++;
7278 		      pP1++;
7279 		      pP2++;
7280 		      *buffer = 0;
7281 		    }
7282 		}
7283 	    }
7284 	}
7285       else
7286 	{
7287 	  /*f633 */
7288 	  channel_size = (scan2.depth > 8) ? 2 : 1;
7289 
7290 	  if (rz->rescount < scan2.resolution_y)
7291 	    {
7292 	      if (rz->bytesperline != 0)
7293 		{
7294 		  SANE_Int value;
7295 
7296 		  for (lfa54 = 0; lfa54 < rz->bytesperline; lfa54++)
7297 		    {
7298 		      value =
7299 			(((scan2.resolution_y -
7300 			   rz->rescount) * data_lsb_get (pP2,
7301 							 channel_size)) +
7302 			 (rz->rescount * data_lsb_get (pP1, channel_size))) /
7303 			scan2.resolution_y;
7304 		      data_lsb_set (buffer, value, channel_size);
7305 
7306 		      pP1 += channel_size;
7307 		      pP2 += channel_size;
7308 		      buffer += channel_size;
7309 		    }
7310 		}
7311 	    }
7312 	  else
7313 	    memcpy (buffer, rz->v3628, rz->bytesperline);	/*f6a8 */
7314 	}
7315 
7316       /*f736 */
7317       if (lfa68 != 0)
7318 	{
7319 	  SANE_Byte *temp;
7320 
7321 	  if (arrangeline2 == FIX_BY_SOFT)
7322 	    {
7323 	      /*f74b */
7324 	      if (scan2.colormode == CM_COLOR)
7325 		rst =
7326 		  Arrange_Colour (dev, rz->v3624, line_size, &transferred);
7327 	      else
7328 		rst =
7329 		  Arrange_NonColour (dev, rz->v3624, line_size, &transferred);
7330 	    }
7331 	  else
7332 	    rst = Read_Block (dev, line_size, rz->v3624, &transferred);	/*f77a */
7333 
7334 	  /*f78c */
7335 	  /* swap buffers */
7336 	  temp = rz->v3628;
7337 	  rz->v3628 = rz->v362c;
7338 	  rz->v362c = temp;
7339 
7340 	  Resize_Increase (temp, rz->resolution_x, rz->towidth, rz->v3624,
7341 			   scan2.resolution_x, rz->fromwidth, rz->mode);
7342 	}
7343       else
7344 	rst = OK;
7345     }
7346 
7347   DBG (DBG_FNC, "- Read_ResizeBlock(*transferred=%i): %i\n", *transferred,
7348        rst);
7349 
7350   return rst;
7351 }
7352 
7353 static void
Split_into_12bit_channels(SANE_Byte * destino,SANE_Byte * fuente,SANE_Int size)7354 Split_into_12bit_channels (SANE_Byte * destino, SANE_Byte * fuente,
7355 			   SANE_Int size)
7356 {
7357   /*
7358      Each letter represents a bit
7359      abcdefgh 12345678 lmnopqrs << before splitting
7360      [efgh1234 0000abcd] [lmnopqrs 00005678]  << after splitting, in memory
7361      [0000abcd efgh1234] [00005678 lmnopqrs]  << resulting channels
7362    */
7363 
7364   DBG (DBG_FNC, "> Split_into_12bit_channels(*destino, *fuente, size=%i\n",
7365        size);
7366 
7367   if ((destino != NULL) && (fuente != NULL))
7368     {
7369       if ((size - (size & 0x03)) != 0)
7370 	{
7371 	  SANE_Int C;
7372 
7373 	  C = (size - (size & 0x03) + 3) / 4;
7374 	  do
7375 	    {
7376 	      *destino = _B0 ((*(fuente + 1) >> 4) + (*fuente << 4));
7377 	      *(destino + 1) = _B0 (*fuente >> 4);
7378 	      *(destino + 2) = _B0 (*(fuente + 2));
7379 	      *(destino + 3) = *(fuente + 1) & 0x0f;
7380 	      destino += 4;
7381 	      fuente += 3;
7382 	      C--;
7383 	    }
7384 	  while (C > 0);
7385 	}
7386 
7387        /**/ if ((size & 0x03) != 0)
7388 	{
7389 	  *destino = _B0 ((*(fuente + 1) >> 4) + (*fuente << 4));
7390 	  *(destino + 1) = _B0 (*fuente >> 4);
7391 	}
7392     }
7393 }
7394 
7395 static SANE_Int
Read_NonColor_Block(struct st_device * dev,SANE_Byte * buffer,SANE_Int buffer_size,SANE_Byte ColorMode,SANE_Int * transferred)7396 Read_NonColor_Block (struct st_device *dev, SANE_Byte * buffer,
7397 		     SANE_Int buffer_size, SANE_Byte ColorMode,
7398 		     SANE_Int * transferred)
7399 {
7400   /* FA50   05DA0048 buffer
7401      FA54   0000F906 buffer_size
7402      FA58   00       ColorMode
7403    */
7404 
7405   SANE_Int rst = OK;
7406   SANE_Int lfa38 = 0;
7407   SANE_Byte *gamma = v1600;
7408   SANE_Int block_bytes_per_line;
7409   SANE_Int mysize;
7410   SANE_Byte *mybuffer;
7411 
7412   DBG (DBG_FNC,
7413        "+ Read_NonColor_Block(*buffer, buffer_size=%i, ColorMode=%s):\n",
7414        buffer_size, dbg_colour (ColorMode));
7415 
7416   if (ColorMode != CM_GRAY)
7417     {
7418       /* Lineart mode */
7419       if ((lineart_width & 7) != 0)
7420 	lfa38 = 8 - (lineart_width & 7);
7421       block_bytes_per_line = (lineart_width + 7) / 8;
7422     }
7423   else
7424     block_bytes_per_line = line_size;
7425   /*61b2 */
7426 
7427   mysize = (buffer_size / block_bytes_per_line) * bytesperline;
7428   mybuffer = (SANE_Byte *) malloc (mysize * sizeof (SANE_Byte));	/*fa40 */
7429 
7430   if (mybuffer != NULL)
7431     {
7432       SANE_Int LinesCount;
7433       SANE_Int mysize4lines;
7434       SANE_Byte *pBuffer = buffer;
7435       SANE_Byte *pImage = NULL;	/* fa30 */
7436       SANE_Int puntero;
7437       SANE_Int value;
7438 
7439       do
7440 	{
7441 	  mysize4lines =
7442 	    (mysize <=
7443 	     dev->Reading->Size4Lines) ? mysize : dev->Reading->Size4Lines;
7444 	  LinesCount = mysize4lines / bytesperline;
7445 
7446 	  if (ColorMode == CM_GRAY)
7447 	    {
7448 	      if (scan2.depth == 12)
7449 		{
7450 		  /* 633b */
7451 		  /*GRAY Bit mode 12 */
7452 		  rst =
7453 		    Scan_Read_BufferA (dev, (mysize4lines * 3) / 4, 0,
7454 				       mybuffer, transferred);
7455 		  if (rst == OK)
7456 		    {
7457 		      pImage = mybuffer;
7458 		      pBuffer += LinesCount * block_bytes_per_line;
7459 		      while (LinesCount > 0)
7460 			{
7461 			  Split_into_12bit_channels (mybuffer, pImage,
7462 						     line_size);
7463 			  pImage += (bytesperline * 3) / 4;
7464 			  LinesCount--;
7465 			}
7466 		    }
7467 		  else
7468 		    break;
7469 		}
7470 	      else
7471 		{
7472 		  /* grayscale 8 and 16 bits */
7473 
7474 		  SANE_Int channel_size;
7475 
7476 		  rst =
7477 		    Scan_Read_BufferA (dev, mysize4lines, 0, mybuffer,
7478 				       transferred);
7479 
7480 		  if (rst == OK)
7481 		    {
7482 		      channel_size = (scan2.depth > 8) ? 2 : 1;
7483 
7484 		      pImage = mybuffer;
7485 
7486 		      /* No gamma tables */
7487 		      while (LinesCount > 0)
7488 			{
7489 			  if (line_size > 0)
7490 			    {
7491 			      puntero = 0;
7492 			      do
7493 				{
7494 				  value =
7495 				    data_lsb_get (pImage + puntero,
7496 						  channel_size);
7497 
7498 				  if (gamma != NULL)
7499 				    value +=
7500 				      *gamma << (8 * (channel_size - 1));
7501 
7502 				  data_lsb_set (pBuffer, value, channel_size);
7503 
7504 				  pBuffer += channel_size;
7505 				  puntero += channel_size;
7506 				}
7507 			      while (puntero < line_size);
7508 			    }
7509 			  pImage += bytesperline;
7510 			  LinesCount--;
7511 			}
7512 		    }
7513 		  else
7514 		    break;
7515 		}
7516 	    }
7517 	  else
7518 	    {
7519 	      /*6429 */
7520 	      /* LINEART */
7521 	      SANE_Int desp;
7522 	      rst =
7523 		Scan_Read_BufferA (dev, mysize4lines, 0, mybuffer,
7524 				   transferred);
7525 	      if (rst == OK)
7526 		{
7527 		  pImage = mybuffer;
7528 		  while (LinesCount > 0)
7529 		    {
7530 		      if (lineart_width > 0)
7531 			{
7532 			  desp = 0;
7533 			  do
7534 			    {
7535 			      if ((desp % 7) == 0)
7536 				*pBuffer = 0;
7537 
7538 			      /* making a byte bit per bit */
7539 			      *pBuffer = *pBuffer << 1;
7540 
7541 			      /* bit 1 if data is under thresholdh value */
7542 			      if (*(pImage + desp) >= binarythresholdh)	/* binarythresholdh = 0x0c */
7543 				*pBuffer = *pBuffer | 1;
7544 
7545 			      desp++;
7546 			      if ((desp % 7) == 0)
7547 				pBuffer++;
7548 
7549 			    }
7550 			  while (desp < lineart_width);
7551 			}
7552 
7553 		      if (lfa38 != 0)
7554 			{
7555 			  *pBuffer = (*pBuffer << lfa38);
7556 			  pBuffer++;
7557 			}
7558 		      /* 64b0 */
7559 		      pImage += bytesperline;
7560 		      LinesCount--;
7561 		    }
7562 		}
7563 	      else
7564 		break;
7565 	    }
7566 	  /* 64c0 */
7567 	  mysize -= mysize4lines;
7568 	}
7569       while ((mysize > 0) && (dev->status->cancel == FALSE));
7570 
7571       free (mybuffer);
7572     }
7573   else
7574     rst = ERROR;
7575 
7576   DBG (DBG_FNC, "- Read_NonColor_Block(*transferred=%i): %i\n", *transferred,
7577        rst);
7578 
7579   return rst;
7580 }
7581 
7582 static SANE_Int
Read_Block(struct st_device * dev,SANE_Int buffer_size,SANE_Byte * buffer,SANE_Int * transferred)7583 Read_Block (struct st_device *dev, SANE_Int buffer_size, SANE_Byte * buffer,
7584 	    SANE_Int * transferred)
7585 {
7586   /*
7587      SANE_Int buffer_size          fa80
7588      SANE_Byte *buffer    fa7c
7589    */
7590 /*
7591 scan2:
7592 04F0155C  01 08 00 02 03 00 58 02  ..X
7593 04F01564  58 02 58 02 C5 00 00 00  XXÅ...
7594 04F0156C  B4 07 00 00 8B 01 00 00  ´..‹..
7595 04F01574  10 06 00 00 EC 13 00 00  ..ì..
7596 04F0157C  B2 07 00 00 B4 07 00 00  ²..´..
7597 04F01584  CF 08 00 00              Ï..
7598 
7599 arrangeline2 = 1
7600 */
7601   SANE_Int rst, LinesCount;
7602   SANE_Int mysize;
7603   SANE_Byte *readbuffer = NULL;
7604   SANE_Byte *pImage = NULL;
7605 
7606   DBG (DBG_FNC, "+ Read_Block(buffer_size=%i, *buffer):\n", buffer_size);
7607 
7608   rst = ERROR;
7609   *transferred = 0;
7610 
7611   if ((scan2.colormode != CM_COLOR) && (scan2.channel == 3)
7612       && (arrangeline2 != FIX_BY_SOFT))
7613     {
7614       /*6510 */
7615       return Read_NonColor_Block (dev, buffer, buffer_size, scan2.colormode,
7616 				  transferred);
7617     }
7618 
7619   /*6544 */
7620   mysize = (buffer_size / line_size) * bytesperline;
7621   readbuffer = (SANE_Byte *) malloc (mysize * sizeof (SANE_Byte));
7622   pImage = buffer;
7623 
7624   if (readbuffer != NULL)
7625     {
7626       do
7627 	{
7628 	  buffer_size =
7629 	    (dev->Reading->Size4Lines <
7630 	     mysize) ? dev->Reading->Size4Lines : mysize;
7631 	  LinesCount = buffer_size / bytesperline;
7632 
7633 	  if (scan2.depth == 12)
7634 	    {
7635 	      rst =
7636 		Scan_Read_BufferA (dev, buffer_size, 0, readbuffer,
7637 				   transferred);
7638 	      if (rst == OK)
7639 		{
7640 		  if (LinesCount > 0)
7641 		    {
7642 		      SANE_Byte *destino, *fuente;
7643 		      destino = buffer;
7644 		      fuente = readbuffer;
7645 		      do
7646 			{
7647 			  Split_into_12bit_channels (destino, fuente,
7648 						     line_size);
7649 			  destino += line_size;
7650 			  fuente += (bytesperline * 3) / 4;
7651 			  LinesCount--;
7652 			}
7653 		      while (LinesCount > 0);
7654 		    }
7655 		}
7656 	      else
7657 		break;
7658 	    }
7659 	  else
7660 	    {
7661 	      /*65d9 */
7662 	      rst =
7663 		Scan_Read_BufferA (dev, buffer_size, 0, readbuffer,
7664 				   transferred);
7665 	      if (rst == OK)
7666 		{
7667 		  memcpy (pImage, readbuffer, *transferred);
7668 
7669 		  /* apply white shading correction */
7670 		  if ((RTS_Debug->wshading == TRUE)
7671 		      && (scan2.scantype == ST_NORMAL))
7672 		    WShading_Emulate (pImage, &wshading->ptr, *transferred,
7673 				      scan2.depth);
7674 
7675 		  pImage += *transferred;
7676 		}
7677 	      else
7678 		break;
7679 	    }
7680 	  /*6629 */
7681 	  mysize -= buffer_size;
7682 	}
7683       while ((mysize > 0) && (dev->status->cancel == FALSE));
7684 
7685       free (readbuffer);
7686     }
7687 
7688   DBG (DBG_FNC, "- Read_Block(*transferred=%i): %i\n", *transferred, rst);
7689 
7690   return rst;
7691 }
7692 
7693 static SANE_Int
Scan_Read_BufferA(struct st_device * dev,SANE_Int buffer_size,SANE_Int arg2,SANE_Byte * pBuffer,SANE_Int * bytes_transferred)7694 Scan_Read_BufferA (struct st_device *dev, SANE_Int buffer_size, SANE_Int arg2,
7695 		   SANE_Byte * pBuffer, SANE_Int * bytes_transferred)
7696 {
7697   SANE_Int rst = OK;
7698   SANE_Byte *ptBuffer = NULL;
7699   SANE_Byte *ptImg = NULL;
7700   struct st_readimage *rd = dev->Reading;
7701 
7702   DBG (DBG_FNC,
7703        "+ Scan_Read_BufferA(buffer_size=%i, arg2, *pBuffer, *bytes_transferred):\n",
7704        buffer_size);
7705 
7706   arg2 = arg2;			/* silence gcc */
7707   *bytes_transferred = 0;
7708 
7709   if (pBuffer != NULL)
7710     {
7711       ptBuffer = pBuffer;
7712 
7713       while ((buffer_size > 0) && (rst == OK)
7714 	     && (dev->status->cancel == FALSE))
7715 	{
7716 	  /* Check if we've already started */
7717 	  if (rd->Starting == TRUE)
7718 	    {
7719 	      /* Get channels per dot and channel's size in bytes */
7720 	      SANE_Byte data;
7721 
7722 	      rd->Channels_per_dot = 1;
7723 	      if (Read_Byte (dev->usb_handle, 0xe812, &data) == OK)
7724 		{
7725 		  data = data >> 6;
7726 		  if (data != 0)
7727 		    rd->Channels_per_dot = data;
7728 		}
7729 
7730 	      rd->Channel_size = 1;
7731 	      if (Read_Byte (dev->usb_handle, 0xee0b, &data) == OK)
7732 		if (((data & 0x40) != 0) && ((data & 0x08) == 0))
7733 		  rd->Channel_size = 2;
7734 
7735 	      rd->RDStart = rd->DMABuffer;
7736 	      rd->RDSize = 0;
7737 	      rd->DMAAmount = 0;
7738 	      rd->Starting = FALSE;
7739 	    }
7740 
7741 	  /* Is there any data to read from scanner? */
7742 	  if ((rd->ImageSize > 0) && (rd->RDSize == 0))
7743 	    {
7744 	      /* Try to read from scanner all possible data to fill DMABuffer */
7745 	      if (rd->RDSize < rd->DMABufferSize)
7746 		{
7747 		  SANE_Int iAmount, dofree;
7748 
7749 		  /* Check if we have already notify buffer size */
7750 		  if (rd->DMAAmount <= 0)
7751 		    {
7752 		      /* Initially I suppose that I can read all image */
7753 		      iAmount = min (rd->ImageSize, rd->Max_Size);
7754 		      rd->DMAAmount =
7755 			((RTS_Debug->dmasetlength * 2) / iAmount) * iAmount;
7756 		      rd->DMAAmount = min (rd->DMAAmount, rd->ImageSize);
7757 		      Reading_BufferSize_Notify (dev, 0, rd->DMAAmount);
7758 		      iAmount = min (iAmount, rd->DMABufferSize - rd->RDSize);
7759 		    }
7760 		  else
7761 		    {
7762 		      iAmount = min (rd->DMAAmount, rd->ImageSize);
7763 		      iAmount = min (iAmount, rd->Max_Size);
7764 		    }
7765 
7766 		  /* Allocate buffer to read image if it's necessary */
7767 		  if ((rd->RDSize == 0) && (iAmount <= buffer_size))
7768 		    {
7769 		      ptImg = ptBuffer;
7770 		      dofree = FALSE;
7771 		    }
7772 		  else
7773 		    {
7774 		      ptImg =
7775 			(SANE_Byte *) malloc (iAmount * sizeof (SANE_Byte));
7776 		      dofree = TRUE;
7777 		    }
7778 
7779 		  if (ptImg != NULL)
7780 		    {
7781 		      /* We must wait for scanner to get data */
7782 		      SANE_Int opStatus, sc;
7783 
7784 		      sc = (iAmount < rd->Max_Size) ? TRUE : FALSE;
7785 		      opStatus = Reading_Wait (dev, rd->Channels_per_dot,
7786 					       rd->Channel_size,
7787 					       iAmount,
7788 					       &rd->Bytes_Available, 60, sc);
7789 
7790 		      /* If something fails, perhaps we can read some bytes... */
7791 		      if (opStatus != OK)
7792 			{
7793 			  if (rd->Bytes_Available > 0)
7794 			    iAmount = rd->Bytes_Available;
7795 			  else
7796 			    rst = ERROR;
7797 			}
7798 
7799 		      if (rst == OK)
7800 			{
7801 			  /* Try to read from scanner */
7802 			  SANE_Int transferred = 0;
7803 			  opStatus =
7804 			    Bulk_Operation (dev, BLK_READ, iAmount, ptImg,
7805 					    &transferred);
7806 
7807 			  DBG (DBG_FNC,
7808 			       "> Scan_Read_BufferA: Bulk read %i bytes\n",
7809 			       transferred);
7810 
7811 			  /*if something fails may be we can read some bytes */
7812 			  iAmount = (SANE_Int) transferred;
7813 			  if (iAmount != 0)
7814 			    {
7815 			      /* Lets copy data into DMABuffer if it's necessary */
7816 			      if (ptImg != ptBuffer)
7817 				{
7818 				  SANE_Byte *ptDMABuffer;
7819 
7820 				  ptDMABuffer = rd->RDStart + rd->RDSize;
7821 				  if ((ptDMABuffer - rd->DMABuffer) >=
7822 				      rd->DMABufferSize)
7823 				    ptDMABuffer -= rd->DMABufferSize;
7824 
7825 				  if ((ptDMABuffer + iAmount) >=
7826 				      (rd->DMABuffer + rd->DMABufferSize))
7827 				    {
7828 				      SANE_Int rest =
7829 					iAmount - (rd->DMABufferSize -
7830 						   (ptDMABuffer -
7831 						    rd->DMABuffer));
7832 				      memcpy (ptDMABuffer, ptImg,
7833 					      iAmount - rest);
7834 				      memcpy (rd->DMABuffer,
7835 					      ptImg + (iAmount - rest), rest);
7836 				    }
7837 				  else
7838 				    memcpy (ptDMABuffer, ptImg, iAmount);
7839 				  rd->RDSize += iAmount;
7840 				}
7841 			      else
7842 				{
7843 				  *bytes_transferred += iAmount;
7844 				  buffer_size -= iAmount;
7845 				}
7846 
7847 			      rd->DMAAmount -= iAmount;
7848 			      rd->ImageSize -= iAmount;
7849 			    }
7850 			  else
7851 			    rst = ERROR;
7852 			}
7853 
7854 		      /* Lets free buffer */
7855 		      if (dofree == TRUE)
7856 			{
7857 			  free (ptImg);
7858 			  ptImg = NULL;
7859 			}
7860 		    }
7861 		  else
7862 		    rst = ERROR;
7863 		}
7864 	    }
7865 
7866 	  /* is there any data read from scanner? */
7867 	  if (rd->RDSize > 0)
7868 	    {
7869 	      /* Add to the given buffer as many bytes as possible */
7870 	      SANE_Int iAmount;
7871 
7872 	      iAmount = min (buffer_size, rd->RDSize);
7873 	      if ((rd->RDStart + iAmount) >=
7874 		  (rd->DMABuffer + rd->DMABufferSize))
7875 		{
7876 		  SANE_Int rest =
7877 		    rd->DMABufferSize - (rd->RDStart - rd->DMABuffer);
7878 		  memcpy (ptBuffer, rd->RDStart, rest);
7879 		  memcpy (ptBuffer + rest, rd->DMABuffer, iAmount - rest);
7880 		  rd->RDStart = rd->DMABuffer + (iAmount - rest);
7881 		}
7882 	      else
7883 		{
7884 		  memcpy (ptBuffer, rd->RDStart, iAmount);
7885 		  rd->RDStart += iAmount;
7886 		}
7887 
7888 	      ptBuffer += iAmount;
7889 	      rd->RDSize -= iAmount;
7890 	      buffer_size -= iAmount;
7891 	      *bytes_transferred += iAmount;
7892 
7893 	      /* if there isn't any data in DMABuffer we can point RDStart
7894 	         to the beginning of DMABuffer */
7895 	      if (rd->RDSize == 0)
7896 		rd->RDStart = rd->DMABuffer;
7897 	    }
7898 
7899 	  /* in case of all data is read we return OK with bytes_transferred = 0 */
7900 	  if ((*bytes_transferred == 0)
7901 	      || ((rd->RDSize == 0) && (rd->ImageSize == 0)))
7902 	    break;
7903 	}
7904 
7905       if (rst == ERROR)
7906 	RTS_DMA_Cancel (dev);
7907     }
7908 
7909   DBG (DBG_FNC, "->   *bytes_transferred=%i\n", *bytes_transferred);
7910   DBG (DBG_FNC, "->   Reading->ImageSize=%i\n", rd->ImageSize);
7911   DBG (DBG_FNC, "->   Reading->DMAAmount=%i\n", rd->DMAAmount);
7912   DBG (DBG_FNC, "->   Reading->RDSize   =%i\n", rd->RDSize);
7913 
7914   DBG (DBG_FNC, "- Scan_Read_BufferA: %i\n", rst);
7915 
7916   return rst;
7917 }
7918 
7919 static SANE_Int
Reading_BufferSize_Get(struct st_device * dev,SANE_Byte channels_per_dot,SANE_Int channel_size)7920 Reading_BufferSize_Get (struct st_device *dev, SANE_Byte channels_per_dot,
7921 			SANE_Int channel_size)
7922 {
7923   /* returns the amount of bytes in scanner's buffer ready to be read */
7924 
7925   SANE_Int rst;
7926 
7927   DBG (DBG_FNC,
7928        "+ Reading_BufferSize_Get(channels_per_dot=%i, channel_size=%i):\n",
7929        channels_per_dot, channel_size);
7930 
7931   rst = 0;
7932 
7933   if (channel_size > 0)
7934     {
7935       SANE_Int myAmount;
7936 
7937       if (channels_per_dot < 1)
7938 	{
7939 	  /* read channels per dot from registers */
7940 	  if (Read_Byte (dev->usb_handle, 0xe812, &channels_per_dot) == OK)
7941 	    channels_per_dot = _B0 (channels_per_dot >> 6);
7942 
7943 	  if (channels_per_dot == 0)
7944 	    channels_per_dot++;
7945 	}
7946 
7947       if (Read_Integer (dev->usb_handle, 0xef16, &myAmount) == OK)
7948 	rst = ((channels_per_dot * 32) / channel_size) * myAmount;
7949     }
7950 
7951   DBG (DBG_FNC, "- Reading_BufferSize_Get: %i bytes\n", rst);
7952 
7953   return rst;
7954 }
7955 
7956 static SANE_Int
Lamp_Warmup(struct st_device * dev,SANE_Byte * Regs,SANE_Int lamp,SANE_Int resolution)7957 Lamp_Warmup (struct st_device *dev, SANE_Byte * Regs, SANE_Int lamp,
7958 	     SANE_Int resolution)
7959 {
7960   SANE_Int rst = OK;
7961 
7962   DBG (DBG_FNC, "+ Lamp_Warmup(*Regs, lamp=%i, resolution=%i)\n", lamp,
7963        resolution);
7964 
7965   if (Regs != NULL)
7966     {
7967       SANE_Byte flb_lamp, tma_lamp;
7968       SANE_Int overdrivetime;
7969 
7970       Lamp_Status_Get (dev, &flb_lamp, &tma_lamp);
7971 
7972       /* ensure that selected lamp is switched on */
7973       if (lamp == FLB_LAMP)
7974 	{
7975 	  overdrivetime = RTS_Debug->overdrive_flb;
7976 
7977 	  if (flb_lamp == 0)
7978 	    {
7979 	      /* FLB-Lamp is turned off, lets turn on */
7980 	      Lamp_Status_Set (dev, Regs, TRUE, FLB_LAMP);
7981 	      waitforpwm = TRUE;
7982 	    }
7983 	}
7984       else
7985 	{
7986 	  /* is tma device attached to scanner ? */
7987 	  if (RTS_isTmaAttached (dev) == TRUE)
7988 	    {
7989 	      overdrivetime = RTS_Debug->overdrive_ta;
7990 
7991 	      if (tma_lamp == 0)
7992 		{
7993 		  /* tma lamp is turned off */
7994 		  Lamp_Status_Set (dev, Regs, FALSE, TMA_LAMP);
7995 		  waitforpwm = TRUE;
7996 		}
7997 	    }
7998 	  else
7999 	    rst = ERROR;
8000 	}
8001 
8002       /* perform warmup process */
8003       if (rst == OK)
8004 	{
8005 	  Lamp_PWM_Setup (dev, lamp);
8006 
8007 	  if (waitforpwm == TRUE)
8008 	    {
8009 	      /*Lamp_PWM_DutyCycle_Set(dev, (lamp == TMA_LAMP)? 0x0e : 0x00); */
8010 
8011 	      if (RTS_Debug->warmup == TRUE)
8012 		{
8013 		  long ticks = GetTickCount () + overdrivetime;
8014 
8015 		  DBG (DBG_VRB, "- Lamp Warmup process. Please wait...\n");
8016 
8017 		  dev->status->warmup = TRUE;
8018 
8019 		  while (GetTickCount () <= ticks)
8020 		    usleep (1000 * 200);
8021 
8022 		  Lamp_PWM_CheckStable (dev, resolution, lamp);
8023 
8024 		}
8025 	      else
8026 		DBG (DBG_VRB, "- Lamp Warmup process disabled.\n");
8027 	    }
8028 
8029 	  /*Lamp_PWM_Setup(dev, lamp);
8030 
8031 	     if (waitforpwm == TRUE)
8032 	     {
8033 	     if (RTS_Debug->warmup == TRUE)
8034 	     Lamp_PWM_CheckStable(dev, resolution, lamp);
8035 
8036 	     waitforpwm = FALSE;
8037 	     } */
8038 	}
8039 
8040     }
8041   else
8042     rst = ERROR;
8043 
8044   dev->status->warmup = FALSE;
8045 
8046   DBG (DBG_FNC, "- Lamp_Warmup: %i\n", rst);
8047 
8048   return rst;
8049 }
8050 
8051 static SANE_Int
Scan_Start(struct st_device * dev)8052 Scan_Start (struct st_device *dev)
8053 {
8054   SANE_Int rst;
8055 
8056   DBG (DBG_FNC, "+ Scan_Start:\n");
8057 
8058   rst = ERROR;
8059   if (RTS_Enable_CCD (dev, dev->init_regs, 0x0f) == OK)
8060     {
8061       SANE_Byte Regs[RT_BUFFER_LEN], mlock;
8062       SANE_Int ypos, xpos, runb1;
8063       struct st_scanparams scancfg;
8064       struct st_hwdconfig hwdcfg;
8065       struct st_calibration myCalib;
8066       long tick;
8067 
8068       memcpy (&Regs, dev->init_regs, RT_BUFFER_LEN * sizeof (SANE_Byte));
8069       memcpy (&scancfg, &scan, sizeof (struct st_scanparams));
8070 
8071       dbg_ScanParams (&scancfg);
8072 
8073       /* reserva buffer 6 dwords en fa84-fa9f */
8074       memset (&hwdcfg, 0, sizeof (struct st_hwdconfig));
8075 
8076       /* wait till lamp is at home (should use timeout
8077          windows driver doesn't use it)
8078        */
8079       tick = GetTickCount () + 10000;
8080       while ((Head_IsAtHome (dev, Regs) == FALSE)
8081 	     && (tick > GetTickCount ()));
8082 
8083       if (v14b4 != 0)
8084 	{
8085 	  SANE_Int lfaa0 = 0;
8086 
8087 	  if (GainOffset_Counter_Inc (dev, &lfaa0) != OK)
8088 	    return 0x02;
8089 	}
8090 
8091       tick = GetTickCount ();
8092 
8093       /* set margin references */
8094       Refs_Set (dev, Regs, &scancfg);
8095 
8096       /* locate head to right position */
8097       Load_StripCoords (scantype, &ypos, &xpos);
8098       if (ypos != 0)
8099 	Head_Relocate (dev, dev->motorcfg->parkhomemotormove, MTR_FORWARD,
8100 		       ypos);
8101 
8102       /* perform lamp warmup */
8103       if (Lamp_Warmup
8104 	  (dev, Regs, (scancfg.scantype == ST_NORMAL) ? FLB_LAMP : TMA_LAMP,
8105 	   scan.resolution_x) == ERROR)
8106 	return ERROR;
8107 
8108       /* Calibration process */
8109 
8110       /*592c */
8111       if (Calib_CreateBuffers (dev, &myCalib, v14b4) != OK)
8112 	return ERROR;
8113 
8114       /*5947 */
8115 
8116 /*
8117 if (Calib_BlackShading_jkd(dev, Regs, &myCalib, &scancfg) == OK)
8118 	Head_ParkHome(dev, TRUE, dev->motorcfg->parkhomemotormove);
8119 */
8120 
8121 /*
8122 if (Calib_test(dev, Regs, &myCalib, &scancfg) == OK )
8123 	Head_ParkHome(dev, TRUE, dev->motorcfg->parkhomemotormove);
8124 */
8125 
8126 /* Calibrate White shading correction */
8127       if ((RTS_Debug->wshading == TRUE) && (scan.scantype == ST_NORMAL))
8128 	if (WShading_Calibrate (dev, Regs, &myCalib, &scancfg) == OK)
8129 	  Head_ParkHome (dev, TRUE, dev->motorcfg->parkhomemotormove);
8130 
8131       hwdcfg.calibrate = RTS_Debug->calibrate;
8132 
8133       if (RTS_Debug->calibrate != 0)
8134 	{
8135 	  /* Let's calibrate */
8136 	  if ((scancfg.colormode != CM_COLOR) && (scancfg.channel == 3))
8137 	    scancfg.colormode = CM_COLOR;
8138 
8139 	  hwdcfg.arrangeline = 0;
8140 
8141 	  if (scan.scantype == ST_NORMAL)
8142 	    {
8143 	      /* Calibration for reflective type */
8144 
8145 	      /*59e3 */
8146 	      memcpy (&Regs, dev->init_regs,
8147 		      RT_BUFFER_LEN * sizeof (SANE_Byte));
8148 
8149 	      if (Calibration (dev, Regs, &scancfg, &myCalib, 0) != OK)
8150 		{
8151 		  if (v14b4 == 0)
8152 		    Calib_FreeBuffers (&myCalib);
8153 		  return ERROR;
8154 		}
8155 	    }
8156 	  else
8157 	    {
8158 	      /*59ed */
8159 	      /* Calibration for negative/slide type */
8160 
8161 	    }
8162 
8163 	  /*5af1 */
8164 	  if (RTS_Debug->ScanWhiteBoard != FALSE)
8165 	    {
8166 	      Head_ParkHome (dev, TRUE, dev->motorcfg->basespeedmotormove);
8167 	      scan.ler = 1;
8168 	    }
8169 
8170 	  scancfg.colormode = scan.colormode;
8171 	}
8172       else
8173 	{
8174 	  /*5b1e */
8175 	  /*Don't calibrate */
8176 	  if (scan.scantype == ST_NORMAL)
8177 	    {
8178 	      Lamp_Status_Set (dev, NULL, TRUE, FLB_LAMP);
8179 	    }
8180 	  else
8181 	    {
8182 	      if ((scan.scantype == ST_TA) || (scan.scantype == ST_NEG))
8183 		{
8184 		  /*SANE_Int ta_y_start; */
8185 		  Lamp_Status_Set (dev, NULL, FALSE, TMA_LAMP);
8186 		  /*ta_y_start =
8187 		     get_value(SCAN_PARAM, TA_Y_START, 0x2508, usbfile);
8188 		     ta_y_start += (((((scan.coord.top * 3) * 5) * 5) * 32) / scancfg.resolution_x);
8189 		     if (ta_y_start >= 500)
8190 		     {
8191 		     Head_Relocate(dev, dev->motorcfg->highspeedmotormove, MTR_FORWARD, ta_y_start);
8192 		     scancfg.coord.top = 1;
8193 		     scan.ler = 1;
8194 		     } else
8195 		     {
8196 		     / *5ba9* /
8197 		     if (ta_y_start > 0)
8198 		     {
8199 		     Head_Relocate(dev, dev->motorcfg->basespeedmotormove, MTR_FORWARD, ta_y_start);
8200 		     scancfg.coord.top = 1;
8201 		     scan.ler = 1;
8202 		     }
8203 		     } */
8204 		}
8205 	    }
8206 	}
8207 
8208       /*5bd0 */
8209       usleep (1000 * 200);
8210 
8211       hwdcfg.scantype = scan.scantype;
8212       hwdcfg.motor_direction = MTR_FORWARD;
8213 
8214       /* Set Origin */
8215       if ((scan.scantype >= ST_NORMAL) || (scan.scantype <= ST_NEG))
8216 	{
8217 	  scancfg.coord.left += scan.ser;
8218 	  scancfg.coord.top += scan.ler;
8219 	}
8220 
8221       hwdcfg.sensorevenodddistance = dev->sensorcfg->evenodd_distance;
8222       hwdcfg.highresolution = (scancfg.resolution_x <= 1200) ? FALSE : TRUE;
8223 
8224       /*5c55 */
8225       /*
8226          if (RTS_Debug->calibrate == FALSE)
8227          {
8228          SANE_Int mytop = (((scancfg.coord.top * 5) * 5) * 16) / scancfg.resolution_y;
8229          if ((scancfg.resolution_y <= 150)&&(mytop < 300))
8230          {
8231          scancfg.coord.top = scancfg.resolution_y / 4;
8232          } else
8233          {
8234          if (mytop < 100)
8235          scancfg.coord.top = scancfg.resolution_y / 12;
8236          }
8237          }
8238        */
8239 
8240       /*5cd9 */
8241       if (compression != FALSE)
8242 	hwdcfg.compression = TRUE;
8243 
8244       /* setting arrangeline option */
8245       hwdcfg.arrangeline = arrangeline;
8246       if (scancfg.resolution_x == 2400)
8247 	{
8248 	  /* 5cfa */
8249 	  if (scancfg.colormode != CM_COLOR)
8250 	    {
8251 	      if ((scancfg.colormode == CM_GRAY) && (scancfg.channel == 3))
8252 		hwdcfg.arrangeline = FIX_BY_SOFT;
8253 	    }
8254 	  else
8255 	    hwdcfg.arrangeline = FIX_BY_SOFT;
8256 	}
8257 
8258       /*5d12 */
8259       if (dev->sensorcfg->type == CCD_SENSOR)
8260 	{
8261 	  /*5d3a */
8262 	  scancfg.coord.left += 24;
8263 	  switch (scancfg.resolution_x)
8264 	    {
8265 	    case 1200:
8266 	      scancfg.coord.left -= 63;
8267 	      break;
8268 	    case 2400:
8269 	      scancfg.coord.left -= 127;
8270 	      break;
8271 	    }
8272 	}
8273       else
8274 	{
8275 	  /*5d5a */
8276 	  /* CIS sensor */
8277 	  /*5d6d */
8278 	  scancfg.coord.left += 50;
8279 	  switch (scancfg.resolution_x)
8280 	    {
8281 	    case 1200:
8282 	      scancfg.coord.left -= 63;
8283 	      break;
8284 	    case 2400:
8285 	      scancfg.coord.left -= 127;
8286 	      break;
8287 	    }
8288 	}
8289 
8290       /* 5d92 */
8291       DBG (DBG_FNC, " ->Scan_Start xStart=%i, xExtent=%i\n",
8292 	   scancfg.coord.left, scancfg.coord.width);
8293 
8294       runb1 = 1;
8295       if (scan.scantype == ST_NORMAL)
8296 	{
8297 	  /*5db7 */
8298 	  if ((scancfg.resolution_x == 1200)
8299 	      || (scancfg.resolution_x == 2400))
8300 	    {
8301 	      /*5e41 */
8302 	      if ((scancfg.resolution_y / 10) > scancfg.coord.top)
8303 		runb1 = 0;
8304 	    }
8305 	  else
8306 	    {
8307 	      if ((scancfg.resolution_x == 600)
8308 		  && (RTS_Debug->usbtype == USB11)
8309 		  && (scancfg.colormode == CM_COLOR))
8310 		{
8311 		  /*5ded */
8312 		  if ((scancfg.resolution_y / 10) > scancfg.coord.top)
8313 		    runb1 = 0;
8314 		}
8315 	      else
8316 		{
8317 		  if ((scancfg.resolution_x == 600)
8318 		      || (scancfg.resolution_x == 300))
8319 		    {
8320 		      /*5e11 */
8321 		      if (scancfg.resolution_y > scancfg.coord.top)
8322 			runb1 = 0;
8323 		    }
8324 		  else
8325 		    runb1 = 0;
8326 		}
8327 	    }
8328 	}
8329       else
8330 	{
8331 	  /*5e7c *//* entra aquí */
8332 	  if ((scancfg.resolution_y / 10) > scancfg.coord.top)
8333 	    runb1 = 0;
8334 	}
8335       /*5eb1 */
8336       if (runb1 == 1)		/*entra */
8337 	{
8338 	  SANE_Int val1 = scancfg.coord.top - (scancfg.resolution_y / 10);
8339 	  scancfg.coord.top -= val1;
8340 	  Head_Relocate (dev, dev->motorcfg->highspeedmotormove, MTR_FORWARD, (dev->motorcfg->resolution / scancfg.resolution_y) * val1);	/*x168 */
8341 	}
8342 
8343       /*5efe */
8344       if (RTS_Debug->calibrate != FALSE)
8345 	{
8346 	  if (use_gamma_tables != FALSE)
8347 	    {
8348 	      hwdcfg.use_gamma_tables = TRUE;
8349 	      hp_gamma->depth = 0;
8350 	    }
8351 
8352 	  /*5f24 */
8353 	  hwdcfg.white_shading = TRUE;
8354 	  hwdcfg.black_shading = TRUE;
8355 	  hwdcfg.unk3 = 0;
8356 	  RTS_Setup (dev, Regs, &scancfg, &hwdcfg, &calibdata->gain_offset);
8357 
8358 	  myCalib.shading_type = 0;
8359 	  myCalib.shadinglength =
8360 	    min (myCalib.shadinglength, scan.shadinglength);
8361 
8362 	  if (scancfg.colormode != CM_COLOR)
8363 	    {
8364 	      if ((scancfg.channel > 0) && (scancfg.channel < 3))
8365 		myCalib.WRef[0] = myCalib.WRef[scancfg.channel];
8366 	    }
8367 
8368 	  RTS_WriteRegs (dev->usb_handle, Regs);
8369 
8370 	  /* apply gamma if required */
8371 	  Gamma_Apply (dev, Regs, &scancfg, &hwdcfg, hp_gamma);
8372 
8373 	  Shading_apply (dev, Regs, &scancfg, &myCalib);
8374 
8375 	  /* Save to file? */
8376 	  if (RTS_Debug->DumpShadingData != FALSE)
8377 	    dump_shading (&myCalib);	/*5ff9 */
8378 	}
8379       else
8380 	RTS_Setup (dev, Regs, &scancfg, &hwdcfg, default_gain_offset);
8381 
8382       /*602a */
8383       RTS_Debug->calibrate = hwdcfg.calibrate;
8384       binarythresholdh = bw_threshold;
8385       binarythresholdl = bw_threshold;
8386       DBG (DBG_FNC, ">  bw threshold -- hi=%i, lo=%i\n", binarythresholdh,
8387 	   binarythresholdl);
8388 
8389       /* set threshold high */
8390       data_lsb_set (&Regs[0x1a0], binarythresholdh, 2);
8391 
8392       /* set threshold low */
8393       data_lsb_set (&Regs[0x19e], binarythresholdl, 2);
8394 
8395       /* if has motorcurves... */
8396       if ((Regs[0xdf] & 0x10) != 0)
8397 	data_bitset (&Regs[0x01], 0x02, 1);
8398 
8399       /* Set MLOCK */
8400       mlock = get_value (SCAN_PARAM, MLOCK, 0, usbfile) & 1;
8401       data_bitset (&Regs[0x00], 0x10, mlock);	       /*---x----*/
8402 
8403       if (dev->motorcfg->changemotorcurrent != FALSE)
8404 	Motor_Change (dev, Regs,
8405 		      Motor_GetFromResolution (scancfg.resolution_x));
8406 
8407       /* set gain control mode */
8408       Lamp_SetGainMode (dev, Regs, scancfg.resolution_x,
8409 			Lamp_GetGainMode (dev, scancfg.resolution_x,
8410 					  scan.scantype));
8411 
8412       RTS_WaitScanEnd (dev, 15000);
8413       if (v14b4 == 0)
8414 	Calib_FreeBuffers (&myCalib);
8415 
8416       /* release motor */
8417       Motor_Release (dev);
8418 
8419 
8420 #ifdef developing
8421 /*	prueba(Regs);
8422 	dbg_registers(Regs);*/
8423       /*WShading_Calibrate(dev, Regs, &myCalib, &scancfg); */
8424       /*shadingtest1(dev, Regs, &myCalib); */
8425 #endif
8426 
8427       if (RTS_Warm_Reset (dev) == OK)
8428 	{
8429 	  RTS_WriteRegs (dev->usb_handle, Regs);
8430 	  usleep (1000 * 500);
8431 
8432 	  if (RTS_Execute (dev) == OK)
8433 	    {
8434 	      Lamp_Status_Timer_Set (dev, 0);
8435 
8436 	      /* Let scanner some time to store some data */
8437 	      if ((dev->chipset->model == RTS8822L_02A)
8438 		  && (scancfg.resolution_x > 2400))
8439 		usleep (1000 * 5000);
8440 
8441 	      rst = OK;
8442 	    }
8443 	}
8444     }
8445 
8446   DBG (DBG_FNC, "- Scan_Start: %i\n", rst);
8447 
8448   return rst;
8449 }
8450 
8451 static SANE_Int
RTS_Setup_Motor(struct st_device * dev,SANE_Byte * Regs,struct st_scanparams * scancfg,SANE_Int somevalue)8452 RTS_Setup_Motor (struct st_device *dev, SANE_Byte * Regs,
8453 		 struct st_scanparams *scancfg, SANE_Int somevalue)
8454 {
8455   SANE_Int rst = ERROR;		/* default */
8456 
8457   DBG (DBG_FNC, "+ RTS_Setup_Motor(*Regs, *scancfg, somevalue=%i):\n",
8458        somevalue);
8459   dbg_ScanParams (scancfg);
8460 
8461   if ((Regs != NULL) && (scancfg != NULL))
8462     {
8463       SANE_Int colormode, mymode;
8464 
8465       colormode = ((scancfg->colormode != CM_COLOR)
8466 		   && (scancfg->channel == 3)) ? 3 : scancfg->colormode;
8467       mymode =
8468 	RTS_GetScanmode (dev, scantype, colormode, scancfg->resolution_x);
8469 
8470       if (mymode != -1)
8471 	{
8472 	  SANE_Int mbs[2] = { 0 };	/* motor back steps */
8473 	  SANE_Int step_size, step_type, dummyline, myvalue, lf02c;
8474 	  struct st_scanmode *sm;
8475 
8476 	  sm = dev->scanmodes[mymode];
8477 
8478 	  /* set motor step type */
8479 	  data_bitset (&Regs[0xd9], 0x70, sm->scanmotorsteptype);	       /*-xxx----*/
8480 
8481 	  /* set motor direction (polarity) */
8482 	  data_bitset (&Regs[0xd9], 0x80, somevalue >> 3);	/*e------- */
8483 
8484 	  /* next value doesn't seem to have any effect */
8485 	  data_bitset (&Regs[0xd9], 0x0f, somevalue);			       /*----efgh*/
8486 
8487 	  /* 0 enable/1 disable motor */
8488 	  data_bitset (&Regs[0xdd], 0x80, somevalue >> 4);	/*d------- */
8489 
8490 	  /* next value doesn't seem to have any effect */
8491 	  data_bitset (&Regs[0xdd], 0x40, somevalue >> 4);		       /*-d------*/
8492 
8493 	  switch (sm->scanmotorsteptype)
8494 	    {
8495 	    case STT_OCT:
8496 	      step_type = 8;
8497 	      break;
8498 	    case STT_QUART:
8499 	      step_type = 4;
8500 	      break;
8501 	    case STT_HALF:
8502 	      step_type = 2;
8503 	      break;
8504 	    default:
8505 	      step_type = 1;
8506 	      break;		/* STT_FULL */
8507 	    }
8508 
8509 	  /* set dummy lines */
8510 	  dummyline = sm->dummyline;
8511 	  if (dummyline == 0)
8512 	    dummyline++;
8513 
8514 	  data_bitset (&Regs[0xd6], 0xf0, dummyline);	/*xxxx---- */
8515 
8516 	  /* Set if motor has curves */
8517 	  data_bitset (&Regs[0xdf], 0x10, ((sm->motorcurve != -1) ? 1 : 0));		 /*---x----*/
8518 
8519 	  /* set last step of deccurve.scanbufferfull table to 16 */
8520 	  data_lsb_set (&Regs[0xea], 0x10, 3);
8521 
8522 	  /* set last step of deccurve.normalscan table to 16 */
8523 	  data_lsb_set (&Regs[0xed], 0x10, 3);
8524 
8525 	  /* set last step of deccurve.smearing table to 16 */
8526 	  data_lsb_set (&Regs[0xf0], 0x10, 3);
8527 
8528 	  /* set last step of deccurve.parkhome table to 16 */
8529 	  data_lsb_set (&Regs[0xf3], 0x10, 3);
8530 
8531 	  /* set step size */
8532 	  step_size =
8533 	    _B0 ((dev->motorcfg->resolution * step_type) /
8534 		 (dummyline * scancfg->resolution_y));
8535 	  data_lsb_set (&Regs[0xe0], step_size - 1, 1);
8536 
8537 	  /* set line exposure time */
8538 	  myvalue = data_lsb_get (&Regs[0x30], 3);
8539 	  myvalue += ((myvalue + 1) % step_size);
8540 	  data_lsb_set (&Regs[0x30], myvalue, 3);
8541 
8542 	  /* set last step of accurve.normalscan table */
8543 	  myvalue = ((myvalue + 1) / step_size) - 1;
8544 	  data_lsb_set (&Regs[0xe1], myvalue, 3);
8545 
8546 	  /* 42b30eb */
8547 	  lf02c = 0;
8548 	  if (sm->motorcurve != -1)
8549 	    {
8550 	      if (sm->motorcurve < dev->mtrsetting_count)
8551 		{
8552 		  struct st_motorcurve *ms = dev->mtrsetting[sm->motorcurve];
8553 		  ms->motorbackstep = sm->motorbackstep;
8554 		}
8555 
8556 	      DBG (DBG_FNC, " -> Setting up step motor using motorcurve %i\n",
8557 		   sm->motorcurve);
8558 	      lf02c = Motor_Setup_Steps (dev, Regs, sm->motorcurve);
8559 
8560 	      /* set motor back steps */
8561 	      mbs[1] = sm->motorbackstep;
8562 	      if (mbs[1] >= (smeardeccurvecount + smearacccurvecount))
8563 		mbs[0] =
8564 		  mbs[1] - (smeardeccurvecount + smearacccurvecount) + 2;
8565 	      else
8566 		mbs[0] = 0;
8567 
8568 	      if (mbs[1] >= (deccurvecount + acccurvecount))
8569 		mbs[1] -= (deccurvecount + acccurvecount) + 2;
8570 	      else
8571 		mbs[1] = 0;
8572 	    }
8573 	  else
8574 	    {
8575 	      /* this scanner hasn't got any motorcurve */
8576 
8577 	      /* set last step of accurve.smearing table (same as accurve.normalscan) */
8578 	      data_lsb_set (&Regs[0xe4], myvalue, 3);
8579 
8580 	      /* set last step of accurve.parkhome table (same as accurve.normalscan) */
8581 	      data_lsb_set (&Regs[0xe7], myvalue, 3);
8582 
8583 	      /* both motorbacksteps are equal */
8584 	      mbs[0] = sm->motorbackstep;
8585 	      mbs[1] = sm->motorbackstep;
8586 	    }
8587 
8588 	  /* show msi and motorbacksteps */
8589 	  DBG (DBG_FNC, " -> msi            = %i\n", sm->msi);
8590 	  DBG (DBG_FNC, " -> motorbackstep1 = %i\n", mbs[0]);
8591 	  DBG (DBG_FNC, " -> motorbackstep2 = %i\n", mbs[1]);
8592 
8593 	  /* set msi */
8594 	  data_bitset (&Regs[0xda], 0xff, _B0 (sm->msi));	/*xxxxxxxx */
8595 	  data_bitset (&Regs[0xdd], 0x03, _B1 (sm->msi));	      /*------xx*/
8596 
8597 	  /* set motorbackstep (a) */
8598 	  data_bitset (&Regs[0xdb], 0xff, _B0 (mbs[0]));	/*xxxxxxxx */
8599 	  data_bitset (&Regs[0xdd], 0x0c, _B1 (mbs[0]));	      /*----xx--*/
8600 
8601 	  /* set motorbackstep (b) */
8602 	  data_bitset (&Regs[0xdc], 0xff, _B0 (mbs[1]));	/*xxxxxxxx */
8603 	  data_bitset (&Regs[0xdd], 0x30, _B1 (mbs[1]));	      /*--xx----*/
8604 
8605 	  /* 328b */
8606 
8607 	  /* get dummy lines count */
8608 	  dummyline = data_bitget (&Regs[0xd6], 0xf0);
8609 
8610 	  myvalue = scancfg->coord.top * (dummyline * step_size);
8611 
8612 	  if (lf02c >= myvalue)
8613 	    scancfg->coord.top = 1;
8614 	  else
8615 	    scancfg->coord.top -= (lf02c / (dummyline * step_size)) - 1;
8616 
8617 	  rst = lf02c;		/* Result from Motor_Setup_Steps */
8618 	}
8619     }
8620 
8621   DBG (DBG_FNC, "- RTS_Setup_Motor: %i\n", rst);
8622 
8623   return rst;
8624 }
8625 
8626 static void
RTS_Setup_Exposure_Times(SANE_Byte * Regs,struct st_scanparams * scancfg,struct st_scanmode * sm)8627 RTS_Setup_Exposure_Times (SANE_Byte * Regs, struct st_scanparams *scancfg,
8628 			  struct st_scanmode *sm)
8629 {
8630   DBG (DBG_FNC, "> RTS_Setup_Exposure_Times\n");
8631 
8632   if ((sm != NULL) && (Regs != NULL) && (scancfg != NULL))
8633     {
8634       SANE_Int myexpt[3], linexpt, a;
8635 
8636       /* calculate line exposure time */
8637       linexpt = sm->ctpc + 1;
8638       if (RTS_Debug->usbtype == USB11)
8639 	linexpt *= sm->multiexposureforfullspeed;
8640 
8641       if (scancfg->depth > 8)
8642 	linexpt *= sm->multiexposurefor16bitmode;
8643 
8644       linexpt--;
8645 
8646       /* generate exposure times for each channel color */
8647       for (a = CL_RED; a <= CL_BLUE; a++)
8648 	{
8649 	  if ((linexpt > sm->mexpt[a]) && (sm->expt[a] == 0))
8650 	    sm->expt[a] = sm->mexpt[a];
8651 
8652 	  myexpt[a] = (sm->expt[a] == 0) ? sm->mexpt[a] : sm->expt[a];
8653 	}
8654 
8655       /* save exposure times */
8656       DBG (DBG_FNC, "-> Exposure times : %04x, %04x, %04x\n", sm->expt[0],
8657 	   sm->expt[1], sm->expt[2]);
8658       data_lsb_set (&Regs[0x36], sm->expt[CL_RED], 3);
8659       data_lsb_set (&Regs[0x3c], sm->expt[CL_GREEN], 3);
8660       data_lsb_set (&Regs[0x42], sm->expt[CL_BLUE], 3);
8661 
8662       /* save maximum exposure times */
8663       DBG (DBG_FNC, "-> Maximum exposure times: %04x, %04x, %04x\n",
8664 	   sm->mexpt[0], sm->mexpt[1], sm->mexpt[2]);
8665       data_lsb_set (&Regs[0x33], sm->mexpt[CL_RED], 3);
8666       data_lsb_set (&Regs[0x39], sm->mexpt[CL_GREEN], 3);
8667       data_lsb_set (&Regs[0x3f], sm->mexpt[CL_BLUE], 3);
8668 
8669       /* save line exposure time */
8670       data_lsb_set (&Regs[0x30], linexpt, 3);
8671 
8672       /* scancfg->expt = lowest value */
8673       scancfg->expt = min (min (myexpt[1], myexpt[2]), myexpt[0]);
8674     }
8675 }
8676 
8677 static SANE_Int
RTS_Setup_Line_Distances(struct st_device * dev,SANE_Byte * Regs,struct st_scanparams * scancfg,struct st_hwdconfig * hwdcfg,SANE_Int mycolormode,SANE_Int arrangeline)8678 RTS_Setup_Line_Distances (struct st_device *dev, SANE_Byte * Regs,
8679 			  struct st_scanparams *scancfg,
8680 			  struct st_hwdconfig *hwdcfg, SANE_Int mycolormode,
8681 			  SANE_Int arrangeline)
8682 {
8683   SANE_Int iLineDistance = 0;
8684 
8685   if (arrangeline == FIX_BY_HARD)
8686     {
8687       /* we don't need to arrange retrieved line */
8688       SANE_Int mylinedistance, myevenodddist;
8689 
8690       mylinedistance =
8691 	(dev->sensorcfg->line_distance * scancfg->resolution_y) /
8692 	dev->sensorcfg->resolution;
8693 
8694       if (hwdcfg->highresolution == TRUE)
8695 	myevenodddist =
8696 	  (hwdcfg->sensorevenodddistance * scancfg->resolution_y) /
8697 	  dev->sensorcfg->resolution;
8698       else
8699 	myevenodddist = 0;
8700 
8701       data_bitset (&Regs[0x149], 0x3f, myevenodddist);
8702       data_bitset (&Regs[0x14a], 0x3f, mylinedistance);
8703       data_bitset (&Regs[0x14b], 0x3f, mylinedistance + myevenodddist);
8704       data_bitset (&Regs[0x14c], 0x3f, mylinedistance * 2);
8705       data_bitset (&Regs[0x14d], 0x3f, (mylinedistance * 2) + myevenodddist);
8706     }
8707   else
8708     {
8709       /* arrange retrieved line */
8710       data_bitset (&Regs[0x149], 0x3f, 0);
8711       data_bitset (&Regs[0x14a], 0x3f, 0);
8712       data_bitset (&Regs[0x14b], 0x3f, 0);
8713       data_bitset (&Regs[0x14c], 0x3f, 0);
8714       data_bitset (&Regs[0x14d], 0x3f, 0);
8715 
8716       if (arrangeline == FIX_BY_SOFT)
8717 	{
8718 	  if (hwdcfg->highresolution == FALSE)
8719 	    {
8720 	      if (mycolormode == CM_COLOR)
8721 		{
8722 		  iLineDistance =
8723 		    (dev->sensorcfg->line_distance * scan2.resolution_y) * 2;
8724 		  iLineDistance =
8725 		    (iLineDistance / dev->sensorcfg->resolution) + 1;
8726 		  if (iLineDistance < 2)
8727 		    iLineDistance = 2;
8728 		}
8729 	    }
8730 	  else
8731 	    {
8732 	      /* bcc */
8733 	      if (mycolormode == CM_COLOR)
8734 		iLineDistance =
8735 		  ((dev->sensorcfg->line_distance * 2) +
8736 		   hwdcfg->sensorevenodddistance) * scan2.resolution_y;
8737 	      else
8738 		iLineDistance =
8739 		  dev->sensorcfg->line_distance * scan2.resolution_y;
8740 
8741 	      iLineDistance =
8742 		(iLineDistance / dev->sensorcfg->resolution) + 1;
8743 	      if (iLineDistance < 2)
8744 		iLineDistance = 2;
8745 	    }
8746 
8747 	  /* c25 */
8748 	  iLineDistance &= 0xffff;
8749 	  v15b4 = (iLineDistance > 0) ? 1 : 0;
8750 	  imagesize += iLineDistance * bytesperline;
8751 	}
8752     }
8753 
8754   DBG (DBG_FNC,
8755        "> RTS_Setup_Line_Distances(*Regs, *scancfg, *hwdcfg, mycolormode=%i, arrangeline=%i): %i\n",
8756        mycolormode, arrangeline, iLineDistance);
8757 
8758   return iLineDistance;
8759 }
8760 
8761 static SANE_Int
RTS_Setup_Depth(SANE_Byte * Regs,struct st_scanparams * scancfg,SANE_Int mycolormode)8762 RTS_Setup_Depth (SANE_Byte * Regs, struct st_scanparams *scancfg,
8763 		 SANE_Int mycolormode)
8764 {
8765   /* channels_per_line = channels_per_dot * scan.width
8766      bytes_per_line = channels_per_line * bits_per_channel
8767    */
8768 
8769   SANE_Int bytes_per_line = 0;
8770 
8771   if ((scancfg != NULL) && (Regs != NULL))
8772     {
8773       SANE_Int channels_per_line =
8774 	data_bitget (&Regs[0x12], 0xc0) * scancfg->coord.width;
8775 
8776       bytes_per_line = channels_per_line;
8777 
8778       /* set bits per channel in shading correction's register (0x1cf) */
8779       if (mycolormode == CM_LINEART)
8780 	{
8781 	  /* lineart mode */
8782 	  bytes_per_line = (bytes_per_line + 7) / 8;
8783 	  data_bitset (&Regs[0x1cf], 0x30, 3);		    /*--11----*/
8784 	}
8785       else
8786 	{
8787 	  /*f0c */
8788 	  switch (scancfg->depth)
8789 	    {
8790 	    case 16:
8791 	      /* 16 bits per channel */
8792 	      bytes_per_line *= 2;
8793 	      data_bitset (&Regs[0x1cf], 0x30, 2);			    /*--10----*/
8794 	      break;
8795 	    case 12:
8796 	      /* 12 bits per channel */
8797 	      bytes_per_line *= 2;
8798 	      data_bitset (&Regs[0x1cf], 0x30, 1);			    /*--01----*/
8799 	      break;
8800 	    default:
8801 	      /* 8 bits per channel */
8802 	      data_bitset (&Regs[0x1cf], 0x30, 0);			    /*--00----*/
8803 	      break;
8804 	    }
8805 	}
8806     }
8807 
8808   return bytes_per_line;
8809 }
8810 
8811 static void
RTS_Setup_Shading(SANE_Byte * Regs,struct st_scanparams * scancfg,struct st_hwdconfig * hwdcfg,SANE_Int bytes_per_line)8812 RTS_Setup_Shading (SANE_Byte * Regs, struct st_scanparams *scancfg,
8813 		   struct st_hwdconfig *hwdcfg, SANE_Int bytes_per_line)
8814 {
8815   DBG (DBG_FNC,
8816        "> RTS_Setup_Shading(*Regs, *scancfg, *hwdcfg, bytes_per_line=%i)\n",
8817        bytes_per_line);
8818 
8819   if ((Regs != NULL) && (hwdcfg != NULL))
8820     {
8821       SANE_Int dots_count, myvalue, myvalue2, mem_available, resolution_ratio,
8822 	sensor_line_distance;
8823       SANE_Int channels, table_size;
8824 
8825       resolution_ratio = Regs[0x0c0] & 0x1f;
8826 
8827       /* 50de */
8828       data_bitset (&Regs[0x1bf], 0x18, hwdcfg->unk3);	       /*---xx---*/
8829 
8830       /* Enable black shading correction ? */
8831       data_bitset (&Regs[0x1cf], 0x08, hwdcfg->black_shading);		/*----x---*/
8832 
8833       /* Enable white shading correction ? */
8834       data_bitset (&Regs[0x1cf], 0x04, hwdcfg->white_shading);		/*-----x--*/
8835 
8836       if ((hwdcfg->white_shading != FALSE) && (hwdcfg->black_shading != FALSE)
8837 	  && (hwdcfg->unk3 != 0))
8838 	data_bitset (&Regs[0x1cf], 0x04, 0);		    /*-----x--*/
8839 
8840       table_size = 0;
8841 
8842       /* if hwdcfg->black_shading */
8843       if ((Regs[0x1cf] & 8) != 0)
8844 	table_size = (resolution_ratio * scancfg->coord.width) * 2;	/* black shading buffer size? */
8845 
8846       /* if hwdcfg->white_shading */
8847       if ((Regs[0x1cf] & 4) != 0)
8848 	table_size += (resolution_ratio * scancfg->coord.width) * 2;	/* white shading buffer size? */
8849 
8850       /* Regs 0x1ba, 0x1bb, 0x1bd, 0x1c0 seem to be 4 pointers
8851          to some buffer related to shading correction */
8852 
8853       Regs[0x1ba] = 0x00;
8854       table_size = (table_size + v160c_block_size - 1) / v160c_block_size;
8855       table_size = ((table_size + 15) / 16) + 16;
8856 
8857       Regs[0x1bf] &= 0xfe;
8858       Regs[0x1bb] = _B0 (table_size);
8859       Regs[0x1bc] = _B1 (table_size);
8860       Regs[0x1bf] |= _B2 (table_size) & 1;	    /*-------x*/
8861 
8862       Regs[0x1bf] &= 0xf9;
8863       Regs[0x1bd] = _B0 (table_size * 2);
8864       Regs[0x1be] = _B1 (table_size * 2);
8865       Regs[0x1bf] |= (_B2 (table_size * 2) & 3) << 1;	       /*-----xx-*/
8866 
8867       data_wide_bitset (&Regs[0x1c0], 0xfffff, table_size * 3);
8868 
8869       mem_available = mem_total - ((table_size * 3) * 16);
8870       sensor_line_distance = Regs[0x14a] & 0x3f;
8871 
8872       /* select case channels_per_dot */
8873       channels = data_lsb_get (&Regs[0x12], 1) >> 6;
8874 
8875       switch (channels)
8876 	{
8877 	case 3:		/* 3 channels per dot */
8878 	  /* 528d */
8879 	  dots_count = bytes_per_line / 3;	/* 882 */
8880 	  myvalue =
8881 	    (((sensor_line_distance + 1) * dots_count) + v160c_block_size -
8882 	     1) / v160c_block_size;
8883 	  myvalue2 = myvalue;
8884 	  mem_available = (mem_available - (myvalue * 3) + 2) / 3;
8885 
8886 	  myvalue += (table_size * 3) * 8;
8887 	  myvalue = ((myvalue * 2) + mem_available);
8888 
8889 	  data_bitset (&Regs[0x1c2], 0xf0, _B2 ((myvalue / 16) + 1));	/* 4 higher bits   xxxx---- */
8890 	  data_wide_bitset (&Regs[0x1c3], 0xffff, (myvalue / 16) + 1);	/* 16 lower bits */
8891 
8892 	  myvalue = myvalue + myvalue2 + mem_available;
8893 	  data_wide_bitset (&Regs[0x1c5], 0xfffff, (myvalue / 16) + 1);
8894 	  break;
8895 	case 2:		/* 2 channels per dot */
8896 	  dots_count = bytes_per_line / 2;
8897 	  myvalue =
8898 	    (((sensor_line_distance + 1) * dots_count) + v160c_block_size -
8899 	     1) / v160c_block_size;
8900 	  mem_available = ((mem_available - myvalue) + 1) / 2;
8901 	  myvalue += (((table_size * 3) + mem_available) / 16) + 1;
8902 
8903 	  data_bitset (&Regs[0x1c2], 0xf0, _B2 (myvalue));	/* 4 higher bits   xxxx---- */
8904 	  data_wide_bitset (&Regs[0x1c3], 0xffff, myvalue);	/* 16 lower bits */
8905 	  break;
8906 	default:
8907 	  dots_count = bytes_per_line;
8908 	  break;
8909 	}
8910 
8911       Regs[0x01c7] &= 0x0f;
8912       Regs[0x01c8] = _B0 ((mem_total - 1) / 16);
8913       Regs[0x01c9] = _B1 ((mem_total - 1) / 16);
8914       Regs[0x01c7] |= (_B2 ((mem_total - 1) / 16) & 0x0f) << 4;
8915 
8916       mem_available -= (dots_count + v160c_block_size - 1) / v160c_block_size;
8917       mem_available /= 16;
8918       Regs[0x0712] &= 0x0f;
8919       Regs[0x0710] = _B0 (mem_available);
8920       Regs[0x0711] = _B1 (mem_available);
8921       Regs[0x0712] |= _B0 (_B2 (mem_available) << 4);	/*xxxx---- */
8922 
8923       Regs[0x0713] = 0x00;
8924       Regs[0x0714] = 0x10;
8925       Regs[0x0715] &= 0xf0;
8926     }
8927 }
8928 
8929 static void
RTS_Setup_Arrangeline(struct st_device * dev,struct st_hwdconfig * hwdcfg,SANE_Int colormode)8930 RTS_Setup_Arrangeline (struct st_device *dev, struct st_hwdconfig *hwdcfg,
8931 		       SANE_Int colormode)
8932 {
8933   dev->scanning->arrange_compression =
8934     (colormode == CM_LINEART) ? FALSE : hwdcfg->compression;
8935 
8936   if ((colormode == CM_LINEART)
8937       || ((colormode == CM_GRAY) && (hwdcfg->highresolution == FALSE)))
8938     arrangeline2 = 0;
8939   else
8940     arrangeline2 = hwdcfg->arrangeline;
8941 
8942   dev->scanning->arrange_hres = hwdcfg->highresolution;
8943   dev->scanning->arrange_sensor_evenodd_dist =
8944     (hwdcfg->highresolution == FALSE) ? 0 : hwdcfg->sensorevenodddistance;
8945 }
8946 
8947 static void
RTS_Setup_Channels(struct st_device * dev,SANE_Byte * Regs,struct st_scanparams * scancfg,SANE_Int mycolormode)8948 RTS_Setup_Channels (struct st_device *dev, SANE_Byte * Regs,
8949 		    struct st_scanparams *scancfg, SANE_Int mycolormode)
8950 {
8951   DBG (DBG_FNC, "> RTS_Setup_Channels(colormode=%i)\n", mycolormode);
8952 
8953   if ((scancfg != NULL) && (Regs != NULL))
8954     {
8955       if ((mycolormode != CM_COLOR) && (mycolormode != 3))
8956 	{
8957 	  /* CM_GRAY || CM_LINEART */
8958 	  if (scancfg->samplerate == LINE_RATE)
8959 	    {
8960 	      /* Setting channels_per_dot to 1 */
8961 	      data_bitset (&Regs[0x12], 0xc0, 1);	/*01------ */
8962 
8963 	      /* setting one rgb_channel_order */
8964 	      data_bitset (&Regs[0x12], 0x03, dev->sensorcfg->rgb_order[scancfg->channel]);		     /*------xx*/
8965 
8966 	      /* set sensor_channel_color_order */
8967 	      data_bitset (&Regs[0x60a], 0x3f, 6);		    /*--xxxxxx*/
8968 
8969 	      /* set samplerate */
8970 	      data_bitset (&Regs[0x1cf], 0x40, PIXEL_RATE);		     /*-x------*/
8971 
8972 	      /* set unknown data */
8973 	      data_bitset (&Regs[0x1cf], 0x80, 1);	/*x------- */
8974 
8975 	      if (scancfg->channel == dev->sensorcfg->rgb_order[1])
8976 		{
8977 		  /* mexpts[CL_RED] = mexpts[CL_GREEN] */
8978 		  data_lsb_set (&Regs[0x33], data_lsb_get (&Regs[0x39], 3),
8979 				3);
8980 
8981 		  /* expts[CL_RED] = expts[CL_GREEN] */
8982 		  data_lsb_set (&Regs[0x36], data_lsb_get (&Regs[0x3c], 3),
8983 				3);
8984 		}
8985 	      else if (scancfg->channel == dev->sensorcfg->rgb_order[2])
8986 		{
8987 		  /* mexpts[CL_RED] = mexpts[CL_BLUE] */
8988 		  data_lsb_set (&Regs[0x33], data_lsb_get (&Regs[0x3f], 3),
8989 				3);
8990 
8991 		  /* expts[CL_RED] = expts[CL_BLUE] */
8992 		  data_lsb_set (&Regs[0x36], data_lsb_get (&Regs[0x42], 3),
8993 				3);
8994 		}
8995 	    }
8996 	  else
8997 	    {
8998 	      /* e01 */
8999 	      /* setting channels_per_dot to 2 */
9000 	      data_bitset (&Regs[0x12], 0xc0, 2);
9001 
9002 	      /* set two channel color order */
9003 	      data_bitset (&Regs[0x12], 0x03, dev->sensorcfg->channel_gray[0]);			 /*------xx*/
9004 	      data_bitset (&Regs[0x12], 0x0c, dev->sensorcfg->channel_gray[1]);			 /*----xx--*/
9005 
9006 	      /* set samplerate */
9007 	      data_bitset (&Regs[0x1cf], 0x40, LINE_RATE);
9008 
9009 	      /* set unknown data */
9010 	      data_bitset (&Regs[0x1cf], 0x80, 1);
9011 	    }
9012 	}
9013       else
9014 	{
9015 	  /* CM_COLOR || 3 */
9016 	  /* e42 */
9017 
9018 	  /* setting channels_per_dot to 3 */
9019 	  data_bitset (&Regs[0x12], 0xc0, 3);
9020 
9021 	  /* setting samplerate */
9022 	  data_bitset (&Regs[0x1cf], 0x40, scancfg->samplerate);
9023 
9024 	  /* set unknown data */
9025 	  data_bitset (&Regs[0x1cf], 0x80, 0);
9026 
9027 	  /* set sensor chanel_color_order */
9028 	  data_bitset (&Regs[0x60a], 0x03, dev->sensorcfg->channel_color[2]);		   /*------xx*/
9029 	  data_bitset (&Regs[0x60a], 0x0c, dev->sensorcfg->channel_color[1]);		   /*----xx--*/
9030 	  data_bitset (&Regs[0x60a], 0x30, dev->sensorcfg->channel_color[0]);		   /*--xx----*/
9031 
9032 	  /* set rgb_channel_order */
9033 	  data_bitset (&Regs[0x12], 0x03, dev->sensorcfg->rgb_order[0]);	      /*------xx*/
9034 	  data_bitset (&Regs[0x12], 0x0c, dev->sensorcfg->rgb_order[1]);	      /*----xx--*/
9035 	  data_bitset (&Regs[0x12], 0x30, dev->sensorcfg->rgb_order[2]);	      /*--xx----*/
9036 	}
9037     }
9038 }
9039 
9040 static SANE_Int
RTS_Setup(struct st_device * dev,SANE_Byte * Regs,struct st_scanparams * scancfg,struct st_hwdconfig * hwdcfg,struct st_gain_offset * gain_offset)9041 RTS_Setup (struct st_device *dev, SANE_Byte * Regs,
9042 	   struct st_scanparams *scancfg, struct st_hwdconfig *hwdcfg,
9043 	   struct st_gain_offset *gain_offset)
9044 {
9045   SANE_Int rst = ERROR;		/* default */
9046   SANE_Int lSMode;
9047   SANE_Byte mycolormode;
9048 
9049   DBG (DBG_FNC, "+ RTS_Setup:\n");
9050   dbg_ScanParams (scancfg);
9051   dbg_hwdcfg (hwdcfg);
9052 
9053   mycolormode = scancfg->colormode;
9054   if (scancfg->colormode != CM_COLOR)
9055     {
9056       if (scancfg->colormode == CM_LINEART)
9057 	scancfg->depth = 8;
9058 
9059       if (scancfg->channel == 3)
9060 	{
9061 	  if (scancfg->colormode == CM_GRAY)
9062 	    mycolormode = (hwdcfg->arrangeline != FIX_BY_SOFT) ? 3 : CM_COLOR;
9063 	  else
9064 	    mycolormode = 3;
9065 	}
9066     }
9067 
9068   /* 42b47d6 */
9069   memcpy (&scan2, scancfg, sizeof (struct st_scanparams));
9070 
9071   scantype = hwdcfg->scantype;
9072   lSMode =
9073     RTS_GetScanmode (dev, scantype, mycolormode, scancfg->resolution_x);
9074   if (lSMode >= 0)
9075     {
9076       struct st_scanmode *sm = dev->scanmodes[lSMode];
9077 
9078       if (sm != NULL)
9079 	{
9080 	  SANE_Int dummyline, iLineDistance, resolution_ratio, bytes_per_line;
9081 	  struct st_coords rts_coords;
9082 
9083 	  iLineDistance = 0;
9084 
9085 	  scancfg->timing = sm->timing;
9086 	  scancfg->sensorresolution =
9087 	    dev->timings[scancfg->timing]->sensorresolution;
9088 	  scancfg->shadinglength =
9089 	    (((scancfg->sensorresolution * 17) / 2) + 3) & 0xfffffffc;
9090 	  scancfg->samplerate = sm->samplerate;
9091 
9092 	  hwdcfg->motorplus = sm->motorplus;
9093 
9094 	  /* set systemclock */
9095 	  data_bitset (&Regs[0x00], 0x0f, sm->systemclock);
9096 
9097 	  /* setting exposure times */
9098 	  RTS_Setup_Exposure_Times (Regs, scancfg, sm);
9099 
9100 	  /* setting arranges */
9101 	  RTS_Setup_Arrangeline (dev, hwdcfg, mycolormode);
9102 
9103 	  /* set up line distances */
9104 	  iLineDistance =
9105 	    RTS_Setup_Line_Distances (dev, Regs, scancfg, hwdcfg, mycolormode,
9106 				      arrangeline);
9107 
9108 	  /* 4c67 */
9109 
9110 	  /* setup channel colors */
9111 	  RTS_Setup_Channels (dev, Regs, scancfg, mycolormode);
9112 
9113 	  /* setup depth */
9114 	  bytes_per_line = RTS_Setup_Depth (Regs, scancfg, mycolormode);
9115 
9116 	  /* f61 */
9117 
9118 	  /* Set resolution ratio */
9119 	  resolution_ratio =
9120 	    (scancfg->sensorresolution / scancfg->resolution_x) & 0x1f;
9121 	  data_bitset (&Regs[0xc0], 0x1f, resolution_ratio);
9122 
9123 	  /* set sensor timing values */
9124 	  RTS_Setup_SensorTiming (dev, scancfg->timing, Regs);
9125 
9126 	  data_bitset (&Regs[0xd8], 0x40, ((scantype == ST_NORMAL) ? 0 : 1));		  /*-x------*/
9127 
9128 	  /* Use static head ? */
9129 	  data_bitset (&Regs[0xd8], 0x80, ((hwdcfg->static_head == FALSE) ? 1 : 0));	/*x------- */
9130 
9131 	  /* Setting up gamma */
9132 	  RTS_Setup_Gamma (Regs, hwdcfg);
9133 
9134 	  /* setup shading correction */
9135 	  RTS_Setup_Shading (Regs, scancfg, hwdcfg, bytes_per_line);
9136 
9137 	  /* setup stepper motor */
9138 	  hwdcfg->startpos =
9139 	    RTS_Setup_Motor (dev, Regs, scancfg,
9140 			     hwdcfg->motor_direction | MTR_ENABLED);
9141 
9142 	  /* set coordinates */
9143 	  dummyline = data_bitget (&Regs[0xd6], 0xf0);
9144 
9145 	  if (scancfg->coord.left == 0)
9146 	    scancfg->coord.left++;
9147 	  if (scancfg->coord.top == 0)
9148 	    scancfg->coord.top++;
9149 
9150 	  rts_coords.left = scancfg->coord.left * resolution_ratio;
9151 	  rts_coords.width = scancfg->coord.width * resolution_ratio;
9152 	  rts_coords.top = scancfg->coord.top * dummyline;
9153 	  rts_coords.height =
9154 	    ((Regs[0x14d] & 0x3f) + scancfg->coord.height +
9155 	     iLineDistance) * dummyline;
9156 
9157 	  if ((rts_coords.left & 1) == 0)
9158 	    rts_coords.left++;
9159 
9160 	  RTS_Setup_Coords (Regs, rts_coords.left, rts_coords.top,
9161 			    rts_coords.width, rts_coords.height);
9162 
9163 	  data_bitset (&Regs[0x01], 0x06, 0);		   /*-----xx-*/
9164 
9165 	  /* dummy_scan? */
9166 	  data_bitset (&Regs[0x01], 0x10, hwdcfg->dummy_scan);		    /*---x----*/
9167 
9168 	  data_bitset (&Regs[0x163], 0xc0, 1);	/*xx------ */
9169 
9170 	  if (dev->scanning->arrange_compression != FALSE)
9171 	    {
9172 	      Regs[0x60b] &= 0x8f;
9173 	      data_bitset (&Regs[0x60b], 0x10, 1);			 /*-001----*/
9174 	    }
9175 	  else
9176 	    data_bitset (&Regs[0x60b], 0x7f, 0);		   /*-0000000*/
9177 
9178 	  if (mycolormode == 3)
9179 	    {
9180 	      SANE_Int channels_per_line;
9181 
9182 	      /* Set channels_per_line = channels_per_dot * scan_width */
9183 	      channels_per_line =
9184 		data_bitget (&Regs[0x12], 0xc0) * scancfg->coord.width;
9185 	      data_wide_bitset (&Regs[0x060c], 0x3ffff, channels_per_line);
9186 
9187 	      /* Sets 16 bits per channel */
9188 	      data_bitset (&Regs[0x1cf], 0x30, 2);		    /*--10----*/
9189 
9190 	      Regs[0x60b] |= 0x40;
9191 	      if (v1619 == 0x21)
9192 		{
9193 		  dev->scanning->arrange_compression = FALSE;
9194 		  data_bitset (&Regs[0x60b], 0x10, 0);			    /*---0----*/
9195 		}
9196 
9197 	      switch (scancfg->depth)
9198 		{
9199 		case 8:
9200 		case 16:
9201 		  Regs[0x060b] &= 0xf3;
9202 		  break;
9203 		case 12:
9204 		  Regs[0x060b] = (Regs[0x060b] & 0xfb) | 0x08;
9205 		  break;
9206 		}
9207 
9208 	      if (scancfg->colormode == CM_LINEART)
9209 		data_bitset (&Regs[0x60b], 0x0c, 0);
9210 
9211 	      /* disable gamma correction ¿? */
9212 	      data_bitset (&Regs[0x1d0], 0x40, 0);
9213 	    }
9214 
9215 	  /* 5683 */
9216 	  /* Set calibration table */
9217 	  RTS_Setup_GainOffset (Regs, gain_offset);
9218 
9219 	  rst = OK;
9220 	}
9221     }
9222 
9223   DBG (DBG_FNC, "- RTS_Setup: %i\n", rst);
9224 
9225   return rst;
9226 }
9227 
9228 static void
RTS_Setup_Coords(SANE_Byte * Regs,SANE_Int iLeft,SANE_Int iTop,SANE_Int width,SANE_Int height)9229 RTS_Setup_Coords (SANE_Byte * Regs, SANE_Int iLeft, SANE_Int iTop,
9230 		  SANE_Int width, SANE_Int height)
9231 {
9232   DBG (DBG_FNC,
9233        "> RTS_Setup_Coords(*Regs, iLeft=%i, iTop=%i, width=%i, height=%i)\n",
9234        iLeft, iTop, width, height);
9235 
9236   if (Regs != NULL)
9237     {
9238       /* Set Left coord */
9239       data_lsb_set (&Regs[0xb0], iLeft, 2);
9240 
9241       /* Set Right coord */
9242       data_lsb_set (&Regs[0xb2], iLeft + width, 2);
9243 
9244       /* Set Top coord */
9245       data_lsb_set (&Regs[0xd0], iTop, 2);
9246       data_bitset (&Regs[0xd4], 0x0f, _B2 (iTop));
9247 
9248       /* Set Down coord */
9249       data_lsb_set (&Regs[0xd2], iTop + height, 2);
9250       data_bitset (&Regs[0xd4], 0xf0, _B2 (iTop + height));
9251     }
9252 }
9253 
9254 static void
RTS_Setup_GainOffset(SANE_Byte * Regs,struct st_gain_offset * gain_offset)9255 RTS_Setup_GainOffset (SANE_Byte * Regs, struct st_gain_offset *gain_offset)
9256 {
9257   SANE_Byte fake[] =
9258     { 0x19, 0x15, 0x19, 0x64, 0x64, 0x64, 0x74, 0xc0, 0x74, 0xc0, 0x6d,
9259     0xc0, 0x6d, 0xc0, 0x5f, 0xc0, 0x5f, 0xc0
9260   };
9261 
9262   DBG (DBG_FNC, "> RTS_Setup_GainOffset(*Regs, *gain_offset)\n");
9263   dbg_calibtable (gain_offset);
9264 
9265   if ((Regs != NULL) && (gain_offset != NULL))
9266     {
9267       if (RTS_Debug->calibrate == FALSE)
9268 	{
9269 	  data_bitset (&Regs[0x13], 0x03, gain_offset->pag[CL_RED]);		    /*------xx*/
9270 	  data_bitset (&Regs[0x13], 0x0c, gain_offset->pag[CL_GREEN]);		    /*----xx--*/
9271 	  data_bitset (&Regs[0x13], 0x30, gain_offset->pag[CL_BLUE]);		    /*--xx----*/
9272 
9273 	  memcpy (&Regs[0x14], &fake, 18);
9274 	}
9275       else
9276 	{
9277 	  SANE_Int a;
9278 
9279 	  for (a = CL_RED; a <= CL_BLUE; a++)
9280 	    {
9281 	      /* Offsets */
9282 	      Regs[0x1a + (a * 4)] = _B0 (gain_offset->edcg1[a]);
9283 	      Regs[0x1b + (a * 4)] =
9284 		((gain_offset->edcg1[a] >> 1) & 0x80) | (gain_offset->
9285 							 edcg2[a] & 0x7f);
9286 	      Regs[0x1c + (a * 4)] = _B0 (gain_offset->odcg1[a]);
9287 	      Regs[0x1d + (a * 4)] =
9288 		((gain_offset->odcg1[a] >> 1) & 0x80) | (gain_offset->
9289 							 odcg2[a] & 0x7f);
9290 
9291 	      /* Variable Gain Amplifier */
9292 	      data_bitset (&Regs[0x14 + a], 0x1f, gain_offset->vgag1[a]);
9293 	      data_bitset (&Regs[0x17 + a], 0x1f, gain_offset->vgag2[a]);
9294 	    }
9295 
9296 	  data_bitset (&Regs[0x13], 0x03, gain_offset->pag[CL_RED]);		    /*------xx*/
9297 	  data_bitset (&Regs[0x13], 0x0c, gain_offset->pag[CL_GREEN]);		    /*----xx--*/
9298 	  data_bitset (&Regs[0x13], 0x30, gain_offset->pag[CL_BLUE]);		    /*--xx----*/
9299 	}
9300     }
9301 }
9302 
9303 static void
Calibrate_Free(struct st_cal2 * calbuffers)9304 Calibrate_Free (struct st_cal2 *calbuffers)
9305 {
9306   DBG (DBG_FNC, "> Calibrate_Free(*calbuffers)\n");
9307 
9308   if (calbuffers != NULL)
9309     {
9310       SANE_Int c;
9311 
9312       if (calbuffers->table2 != NULL)
9313 	{
9314 	  free (calbuffers->table2);
9315 	  calbuffers->table2 = NULL;
9316 	}
9317 
9318       for (c = 0; c < 4; c++)
9319 	{
9320 	  if (calbuffers->tables[c] != NULL)
9321 	    {
9322 	      free (calbuffers->tables[c]);
9323 	      calbuffers->tables[c] = NULL;
9324 	    }
9325 	}
9326 
9327       calbuffers->shadinglength1 = 0;
9328       calbuffers->tables_size = 0;
9329       calbuffers->shadinglength3 = 0;
9330     }
9331 }
9332 
9333 static SANE_Int
Calibrate_Malloc(struct st_cal2 * calbuffers,SANE_Byte * Regs,struct st_calibration * myCalib,SANE_Int somelength)9334 Calibrate_Malloc (struct st_cal2 *calbuffers, SANE_Byte * Regs,
9335 		  struct st_calibration *myCalib, SANE_Int somelength)
9336 {
9337   SANE_Int myshadinglength, pos;
9338   SANE_Int rst;
9339 
9340   if ((calbuffers != NULL) && (Regs != NULL) && (myCalib != NULL))
9341     {
9342       if ((Regs[0x1bf] & 0x18) == 0)
9343 	{
9344 	  if ((((Regs[0x1cf] >> 1) & Regs[0x1cf]) & 0x04) != 0)
9345 	    calbuffers->table_count = 2;
9346 	  else
9347 	    calbuffers->table_count = 4;
9348 	}
9349       else
9350 	calbuffers->table_count = 4;
9351 
9352       /*365d */
9353       myshadinglength = myCalib->shadinglength * 2;
9354       calbuffers->shadinglength1 = min (myshadinglength, somelength);
9355 
9356       if ((myshadinglength % somelength) != 0)
9357 	calbuffers->tables_size =
9358 	  (myshadinglength >= somelength) ? somelength * 2 : somelength;
9359       else
9360 	calbuffers->tables_size = somelength;
9361 
9362       if (myshadinglength >= somelength)
9363 	{
9364 	  calbuffers->shadinglength1 =
9365 	    (myshadinglength % calbuffers->shadinglength1) +
9366 	    calbuffers->shadinglength1;
9367 	  calbuffers->shadinglength3 =
9368 	    ((myCalib->shadinglength * 2) / somelength) - 1;
9369 	}
9370       else
9371 	calbuffers->shadinglength3 = 0;
9372 
9373       calbuffers->shadinglength3 =
9374 	(somelength / 16) * calbuffers->shadinglength3;
9375 
9376       rst = OK;
9377       for (pos = 0; pos < calbuffers->table_count; pos++)
9378 	{
9379 	  calbuffers->tables[pos] =
9380 	    (USHORT *) malloc (calbuffers->tables_size * sizeof (USHORT));
9381 	  if (calbuffers->tables[pos] == NULL)
9382 	    {
9383 	      rst = ERROR;
9384 	      break;
9385 	    }
9386 	}
9387 
9388       if (rst == OK)
9389 	{
9390 	  calbuffers->table2 =
9391 	    (USHORT *) malloc (calbuffers->tables_size * sizeof (USHORT));
9392 	  if (calbuffers->table2 == NULL)
9393 	    rst = ERROR;
9394 	}
9395 
9396       if (rst != OK)
9397 	Calibrate_Free (calbuffers);
9398     }
9399   else
9400     rst = ERROR;
9401 
9402   DBG (DBG_FNC,
9403        "> Calibrate_Malloc(*calbuffers, *Regs, *myCalib, somelength=%i): %i\n",
9404        somelength, rst);
9405 
9406   return rst;
9407 }
9408 
9409 static SANE_Int
fn3560(USHORT * table,struct st_cal2 * calbuffers,SANE_Int * tablepos)9410 fn3560 (USHORT * table, struct st_cal2 *calbuffers, SANE_Int * tablepos)
9411 {
9412   /*05FEF974   001F99B0  |table = 001F99B0
9413      05FEF978   05FEFA08  |calbuffers->tables[0] = 05FEFA08
9414      05FEF97C   000000A0  |calbuffers->shadinglength3 = 000000A0
9415      05FEF980   00000348  |calbuffers->shadinglength1 = 00000348
9416      05FEF984   04F01502  |calbuffers->table_count = 04F01502
9417      05FEF988   05FEF998  \Arg6 = 05FEF998
9418    */
9419 
9420   if (table != NULL)
9421     {
9422       SANE_Int pos[4] = { 0, 0, 0, 0 };	/*f960 f964 f968 f96c */
9423       SANE_Int usetable = 0;
9424       SANE_Int a;
9425 
9426       SANE_Int mylength3 = calbuffers->shadinglength1;	/*f97c */
9427       SANE_Byte *pPointer =
9428 	(SANE_Byte *) (table + (calbuffers->shadinglength3 * 16));
9429 
9430       DBG (DBG_FNC, "> fn3560(*table, *calbuffers, *tablepos)\n");
9431 
9432       if (mylength3 > 0)
9433 	{
9434 	  do
9435 	    {
9436 	      if (calbuffers->tables[usetable] != NULL)
9437 		{
9438 		  if (mylength3 <= 16)
9439 		    {
9440 		      if (mylength3 > 0)
9441 			{
9442 			  do
9443 			    {
9444 			      *(calbuffers->tables[usetable] +
9445 				pos[usetable]) = _B0 (*pPointer);
9446 			      pPointer++;
9447 			      pos[usetable]++;
9448 			      mylength3--;
9449 			    }
9450 			  while (mylength3 > 0);
9451 			}
9452 		      break;
9453 		    }
9454 
9455 		  for (a = 0; a < 16; a++)
9456 		    {
9457 		      *(calbuffers->tables[usetable] + pos[usetable]) =
9458 			_B0 (*pPointer);
9459 		      pPointer++;
9460 		      pos[usetable]++;
9461 		    }
9462 		}
9463 
9464 	      mylength3 -= 16;
9465 	      usetable++;
9466 	      if (usetable == calbuffers->table_count)
9467 		usetable = 0;
9468 	    }
9469 	  while (mylength3 > 0);
9470 	}
9471 
9472       /*35f8 */
9473       if (calbuffers->table_count > 0)
9474 	{
9475 	  /* Return position of each table */
9476 	  memcpy (tablepos, pos, sizeof (SANE_Int) * 4);
9477 	}
9478     }
9479 
9480   return OK;
9481 }
9482 
9483 static SANE_Int
Calib_WriteTable(struct st_device * dev,SANE_Byte * table,SANE_Int size,SANE_Int data)9484 Calib_WriteTable (struct st_device *dev, SANE_Byte * table, SANE_Int size,
9485 		  SANE_Int data)
9486 {
9487   SANE_Int rst = ERROR;
9488 
9489   DBG (DBG_FNC, "+ Calib_WriteTable(*table, size=%i):\n", size);
9490 
9491   if ((table != NULL) && (size > 0))
9492     {
9493       SANE_Int transferred;
9494 
9495       if (RTS_DMA_Reset (dev) == OK)
9496 	{
9497 	  /* Send size to write */
9498 	  if (RTS_DMA_Enable_Write (dev, 0x0004, size, data) == OK)
9499 	    /* Send data */
9500 	    rst = Bulk_Operation (dev, BLK_WRITE, size, table, &transferred);
9501 	}
9502     }
9503 
9504   DBG (DBG_FNC, "- Calib_WriteTable: %i\n", rst);
9505 
9506   return rst;
9507 }
9508 
9509 static SANE_Int
Calib_ReadTable(struct st_device * dev,SANE_Byte * table,SANE_Int size,SANE_Int data)9510 Calib_ReadTable (struct st_device *dev, SANE_Byte * table, SANE_Int size,
9511 		 SANE_Int data)
9512 {
9513   SANE_Int rst = ERROR;
9514 
9515   DBG (DBG_FNC, "+ Calib_ReadTable(*table, size=%i):\n", size);
9516 
9517   if ((table != NULL) && (size > 0))
9518     {
9519       SANE_Int transferred;
9520 
9521       if (RTS_DMA_Reset (dev) == OK)
9522 	{
9523 	  /* Send size to read */
9524 	  if (RTS_DMA_Enable_Read (dev, 0x0004, size, data) == OK)
9525 	    /* Retrieve data */
9526 	    rst = Bulk_Operation (dev, BLK_READ, size, table, &transferred);
9527 	}
9528     }
9529 
9530   DBG (DBG_FNC, "- Calib_ReadTable: %i\n", rst);
9531 
9532   return rst;
9533 }
9534 
9535 static SANE_Int
fn3330(struct st_device * dev,SANE_Byte * Regs,struct st_cal2 * calbuffers,SANE_Int sensorchannelcolor,SANE_Int * tablepos,SANE_Int data)9536 fn3330 (struct st_device *dev, SANE_Byte * Regs, struct st_cal2 *calbuffers,
9537 	SANE_Int sensorchannelcolor, SANE_Int * tablepos, SANE_Int data)
9538 {
9539   /*05EEF968   04F0F7F8  |Regs = 04F0F7F8
9540      05EEF96C   02DEC838  |calbuffers->table2 = 02DEC838
9541      05EEF970   05EEFA08  |calbuffers->tables[] = 05EEFA08
9542      05EEF974   00000000  |sensorchannelcolor = 00000000
9543      05EEF978   000000A0  |calbuffers->shadinglength3 = 000000A0
9544      05EEF97C   00000400  |calbuffers->tables_size = 00000400
9545      05EEF980   05EEF998  |&pos = 05EEF998
9546      05EEF984   00221502  |calbuffers->table_count = 00221502
9547      05EEF988   00000000  \data = 00000000
9548    */
9549 
9550   SANE_Int table_count = calbuffers->table_count;	/*f960 */
9551   SANE_Int schcolor = _B0 (sensorchannelcolor);
9552   SANE_Int a = 0;
9553   SANE_Int tablelength = calbuffers->shadinglength3 / table_count;	/*f954 */
9554   SANE_Int val_color = 0;	/*f974 */
9555   SANE_Int val_lineart = 0;	/*f978 */
9556   SANE_Int val_gray = 0;	/*ebx */
9557   SANE_Int value4 = 0;		/*ebp */
9558   SANE_Int size;
9559   SANE_Int rst = OK;
9560 
9561   DBG (DBG_FNC,
9562        "+ fn3330(*Regs, *calbuffers, sensorchannelcolor=%i, *tablepos, data=%i):\n",
9563        sensorchannelcolor, data);
9564 
9565   if (calbuffers->table_count > 0)
9566     {
9567       do
9568 	{
9569 	  if (calbuffers->table_count == 2)
9570 	    {
9571 	      /*338c */
9572 	      if (a != 0)
9573 		{
9574 		  /*3394 */
9575 		  if (_B0 (data) == 0)
9576 		    {
9577 		      val_color = 0x100000;
9578 		      val_lineart = 0x100000;
9579 		      val_gray = 0x200000;
9580 		    }
9581 		  else
9582 		    {
9583 		      /*343a */
9584 		      val_color = 0x300000;
9585 		      val_lineart = 0x300000;
9586 		      val_gray = 0;
9587 		    }
9588 		}
9589 	      else
9590 		{
9591 		  /*33be */
9592 		  if (_B0 (data) == 0)
9593 		    {
9594 		      val_color = 0;
9595 		      val_lineart = 0;
9596 		      val_gray = 0x300000;
9597 		    }
9598 		  else
9599 		    {
9600 		      /*342a */
9601 		      val_color = 0x200000;
9602 		      val_lineart = 0x200000;
9603 		      val_gray = 0x100000;
9604 		    }
9605 		}
9606 	    }
9607 	  else
9608 	    {
9609 	      /*33d5 */
9610 	      switch (a)
9611 		{
9612 		case 0:
9613 		  val_color = 0;
9614 		  val_lineart = 0;
9615 		  val_gray = 0x300000;
9616 		  break;
9617 		case 1:
9618 		  val_color = 0x200000;
9619 		  val_lineart = 0x200000;
9620 		  val_gray = 0x100000;
9621 		  break;
9622 		case 2:
9623 		  val_color = 0x100000;
9624 		  val_lineart = 0x100000;
9625 		  val_gray = 0x200000;
9626 		  break;
9627 		case 3:
9628 		  val_color = 0x300000;
9629 		  val_lineart = 0x300000;
9630 		  val_gray = 0;
9631 		  break;
9632 		}
9633 	    }
9634 
9635 	  /*3449 */
9636 	  switch (schcolor)
9637 	    {
9638 	    case CM_LINEART:
9639 	      size =
9640 		(((Regs[0x1bf] >> 1) & 3) << 0x10) | (Regs[0x1be] << 0x08) |
9641 		Regs[0x1bd];
9642 	      value4 = (tablelength + size) | val_lineart;
9643 	      break;
9644 	    case CM_GRAY:
9645 	      size =
9646 		((Regs[0x1bf] & 1) << 0x10) | (Regs[0x1bc] << 0x08) |
9647 		Regs[0x1bb];
9648 	      value4 = (tablelength + size) | val_gray;
9649 	      break;
9650 	    default:
9651 	      size = _B0 (Regs[0x1ba]);
9652 	      value4 = (tablelength + size) | val_color;
9653 	      break;
9654 	    }
9655 
9656 	  if (Calib_ReadTable
9657 	      (dev, (SANE_Byte *) calbuffers->table2, calbuffers->tables_size,
9658 	       value4) != OK)
9659 	    {
9660 	      rst = ERROR;
9661 	      break;
9662 	    }
9663 
9664 	  memcpy (calbuffers->tables[a], calbuffers->table2, tablepos[a]);
9665 
9666 	  if (tablepos[a + 1] == 0)
9667 	    break;
9668 
9669 	  a++;
9670 	}
9671       while (a < calbuffers->table_count);
9672     }
9673 
9674   DBG (DBG_FNC, "- fn3330: %i\n", rst);
9675 
9676   return rst;
9677 }
9678 
9679 static SANE_Int
fn3730(struct st_device * dev,struct st_cal2 * calbuffers,SANE_Byte * Regs,USHORT * table,SANE_Int sensorchannelcolor,SANE_Int data)9680 fn3730 (struct st_device *dev, struct st_cal2 *calbuffers, SANE_Byte * Regs,
9681 	USHORT * table, SANE_Int sensorchannelcolor, SANE_Int data)
9682 {
9683   /*05FEF9AC   |calbuffers         = 05FEF9F8
9684      05FEF9B0   |Regs               = 04EFF7F8
9685      05FEF9B4   |table              = 001F99B0
9686      05FEF9B8   |sensorchannelcolor = 00000000
9687      05FEF9BC   |data               = 00000000
9688    */
9689 
9690   SANE_Int pos[4] = { 0, 0, 0, 0 };	/*f998 f99c f9a0 f9a4 */
9691   SANE_Int rst;
9692 
9693   DBG (DBG_FNC,
9694        "+ fn3730(*calbuffers, *Regs, *table, sensorchannelcolor=%i, data=%i):\n",
9695        sensorchannelcolor, data);
9696 
9697   fn3560 (table, calbuffers, pos);
9698   rst = fn3330 (dev, Regs, calbuffers, sensorchannelcolor, pos, data);
9699 
9700   DBG (DBG_FNC, "- fn3730: %i\n", rst);
9701 
9702   return rst;
9703 }
9704 
9705 static SANE_Int
Shading_white_apply(struct st_device * dev,SANE_Byte * Regs,SANE_Int channels,struct st_calibration * myCalib,struct st_cal2 * calbuffers)9706 Shading_white_apply (struct st_device *dev, SANE_Byte * Regs,
9707 		     SANE_Int channels, struct st_calibration *myCalib,
9708 		     struct st_cal2 *calbuffers)
9709 {
9710   SANE_Int rst = OK;
9711 
9712   DBG (DBG_FNC, "+ Shading_white_apply(channels=%i)\n", channels);
9713 
9714   /*3e7f */
9715   Calibrate_Malloc (calbuffers, Regs, myCalib,
9716 		    (RTS_Debug->usbtype == USB20) ? 0x200 : 0x40);
9717 
9718   if (channels > 0)
9719     {
9720       /*int a; */
9721       SANE_Int chnl;
9722       SANE_Int pos;		/*fa2c */
9723       SANE_Int transferred;
9724 
9725       rst = ERROR;
9726 
9727       for (chnl = 0; chnl < channels; chnl++)
9728 	{
9729 	  /*for (a = 0; a < myCalib->shadinglength; a++)
9730 	     myCalib->black_shading[chnl][a] = 0x2000; */
9731 	  /* 11 tries */
9732 	  for (pos = 0; pos <= 10; pos++)
9733 	    {
9734 	      /* Send size to write */
9735 	      if (RTS_DMA_Enable_Write
9736 		  (dev, dev->sensorcfg->channel_color[chnl] | 0x14,
9737 		   myCalib->shadinglength, 0) == OK)
9738 		/* Send data */
9739 		Bulk_Operation (dev, BLK_WRITE,
9740 				myCalib->shadinglength * sizeof (USHORT),
9741 				(SANE_Byte *) & myCalib->
9742 				white_shading[chnl][myCalib->first_position -
9743 						    1], &transferred);
9744 
9745 	      /*3df7 */
9746 	      if (fn3730
9747 		  (dev, calbuffers, Regs,
9748 		   &myCalib->white_shading[chnl][myCalib->first_position - 1],
9749 		   dev->sensorcfg->channel_color[chnl], 1) == OK)
9750 		{
9751 		  rst = OK;
9752 		  break;
9753 		}
9754 
9755 	      RTS_DMA_Cancel (dev);
9756 	    }
9757 	}
9758     }
9759 
9760   Calibrate_Free (calbuffers);
9761 
9762   DBG (DBG_FNC, "- Shading_white_apply: %i\n", rst);
9763 
9764   return OK;
9765 }
9766 
9767 static SANE_Int
Shading_black_apply(struct st_device * dev,SANE_Byte * Regs,SANE_Int channels,struct st_calibration * myCalib,struct st_cal2 * calbuffers)9768 Shading_black_apply (struct st_device *dev, SANE_Byte * Regs,
9769 		     SANE_Int channels, struct st_calibration *myCalib,
9770 		     struct st_cal2 *calbuffers)
9771 {
9772   SANE_Int rst = OK;
9773 
9774   DBG (DBG_FNC, "+ Shading_black_apply(channels=%i)\n", channels);
9775 
9776   /* 3d79 */
9777   Calibrate_Malloc (calbuffers, Regs, myCalib,
9778 		    (RTS_Debug->usbtype == USB20) ? 0x200 : 0x40);
9779 
9780   if (channels > 0)
9781     {
9782       /*int a; */
9783       SANE_Int chnl;
9784       SANE_Int pos;		/*fa2c */
9785       SANE_Int transferred;
9786 
9787       rst = ERROR;
9788 
9789       for (chnl = 0; chnl < channels; chnl++)
9790 	{
9791 	  /* 11 tries */
9792 	  /*for (a = 0; a < myCalib->shadinglength; a++)
9793 	     myCalib->black_shading[chnl][a] = 0x2000; */
9794 
9795 	  for (pos = 0; pos <= 10; pos++)
9796 	    {
9797 	      /* Send size to write */
9798 	      if (RTS_DMA_Enable_Write
9799 		  (dev, dev->sensorcfg->channel_color[chnl] | 0x10,
9800 		   myCalib->shadinglength, 0) == OK)
9801 		/* Send data */
9802 		Bulk_Operation (dev, BLK_WRITE,
9803 				myCalib->shadinglength * sizeof (USHORT),
9804 				(SANE_Byte *) & myCalib->
9805 				black_shading[chnl][myCalib->first_position -
9806 						    1], &transferred);
9807 
9808 	      /*3df7 */
9809 	      if (fn3730
9810 		  (dev, calbuffers, Regs,
9811 		   &myCalib->black_shading[chnl][myCalib->first_position - 1],
9812 		   dev->sensorcfg->channel_color[chnl], 0) == OK)
9813 		{
9814 		  rst = OK;
9815 		  break;
9816 		}
9817 
9818 	      RTS_DMA_Cancel (dev);
9819 	    }
9820 	}
9821     }
9822 
9823   /*3e62 */
9824   Calibrate_Free (calbuffers);
9825 
9826   DBG (DBG_FNC, "- Shading_black_apply: %i\n", rst);
9827 
9828   return OK;
9829 }
9830 
9831 static SANE_Int
Shading_apply(struct st_device * dev,SANE_Byte * Regs,struct st_scanparams * myvar,struct st_calibration * myCalib)9832 Shading_apply (struct st_device *dev, SANE_Byte * Regs,
9833 	       struct st_scanparams *myvar, struct st_calibration *myCalib)
9834 {
9835   /*
9836      Regs f1bc
9837      myvar     f020
9838      hwdcfg  e838
9839      arg4      e81c
9840      myCalib   e820
9841    */
9842 
9843   SANE_Int rst;			/* lf9e0 */
9844   SANE_Int myfact;		/* e820 */
9845   SANE_Int shadata;
9846   SANE_Byte channels;		/* f9d4 */
9847   SANE_Int myShadingBase;	/* e818 */
9848 
9849   char lf9d1;
9850   char lf9d0;
9851 
9852   DBG (DBG_FNC, "+ Shading_apply(*Regs, *myvar, *mygamma, *myCalib):\n");
9853   dbg_ScanParams (myvar);
9854 
9855   lf9d0 = (Regs[0x60b] >> 6) & 1;
9856   lf9d1 = (Regs[0x60b] >> 4) & 1;
9857   Regs[0x060b] &= 0xaf;
9858   rst = Write_Byte (dev->usb_handle, 0xee0b, Regs[0x060b]);
9859   if (rst == OK)
9860     {
9861       SANE_Byte colormode = myvar->colormode;	/*fa24 */
9862       SANE_Int le7cc, le7d8;
9863       struct st_cal2 calbuffers;	/* f9f8 */
9864 
9865       if (colormode != CM_COLOR)
9866 	{
9867 	  if (myvar->channel != 3)
9868 	    {
9869 	      if (colormode != 3)
9870 		channels = (myvar->samplerate == PIXEL_RATE) ? 2 : 1;
9871 	      else
9872 		channels = 3;
9873 	    }
9874 	  else
9875 	    {
9876 	      colormode = 3;
9877 	      channels = 3;
9878 	    }
9879 	}
9880       else
9881 	channels = 3;
9882 
9883       /*
9884          White shading formula :    2000H x Target / (Wn-Dn) = White Gain data ----- for 8 times system
9885          White shading formula :    4000H x Target / (Wn-Dn) = White Gain data ----- for 4 times system
9886          For example : Target = 3FFFH   Wn = 2FFFH     Dn = 0040H  and 8 times system operation
9887          then   White Gain = 2000H x 3FFFH / (2FFFH-0040H) = 2AE4H (1.34033 times)
9888        */
9889       /* 3aad */
9890       if (colormode == 3)
9891 	{
9892 	  /*
9893 	     SANE_Int pos;
9894 	     SANE_Int colour;
9895 
9896 	     myShadingBase = shadingbase;
9897 
9898 	     for (colour = 0; colour < channels; colour++)
9899 	     {
9900 	     if (myCalib->white_shading[colour] != NULL)
9901 	     {
9902 	     myfact = shadingfact[colour];
9903 	     if (myCalib->shadinglength > 0)
9904 	     {
9905 	     for (pos = myCalib->first_position - 1; pos < myCalib->shadinglength; pos++)
9906 	     myCalib->white_shading[colour][pos] = (myCalib->white_shading[colour][pos] * myfact) / myShadingBase;
9907 	     }
9908 	     } else break;
9909 	     }
9910 	   */
9911 	}
9912 
9913       /* 3b3b */
9914       if (myCalib->shading_enabled != FALSE)
9915 	{
9916 	  /* 3b46 */
9917 	  SANE_Int colour, pos;
9918 	  le7cc = shadingbase;
9919 	  le7d8 = shadingbase;
9920 
9921 	  DBG (DBG_FNC, "-> Shading type: %i\n", myCalib->shading_type);
9922 
9923 	  for (colour = 0; colour < channels; colour++)
9924 	    {
9925 	      if (colormode == 3)
9926 		le7cc = shadingfact[colour];
9927 
9928 	      myShadingBase = ((Regs[0x1cf] & 2) != 0) ? 0x2000 : 0x4000;
9929 
9930 	      myfact = myCalib->WRef[colour] * myShadingBase;
9931 
9932 	      if (myCalib->shading_type == 2)
9933 		{
9934 		  /*3bd8 */
9935 		  if ((myCalib->black_shading[colour] != NULL)
9936 		      && (myCalib->white_shading[colour] != NULL))
9937 		    {
9938 		      for (pos = myCalib->first_position - 1;
9939 			   pos < myCalib->shadinglength; pos++)
9940 			{
9941 			  if (myCalib->white_shading[colour][pos] == 0)
9942 			    shadata = myShadingBase;
9943 			  else
9944 			    shadata =
9945 			      myfact / myCalib->white_shading[colour][pos];
9946 
9947 			  shadata = min ((shadata * le7cc) / le7d8, 0xff00);
9948 			  myCalib->black_shading[colour][pos] &= 0xff;
9949 			  myCalib->black_shading[colour][pos] |=
9950 			    shadata & 0xff00;
9951 			}
9952 		    }
9953 		  else
9954 		    break;
9955 		}
9956 	      else
9957 		{
9958 		  /*3c63 */
9959 		  if (myCalib->shading_type == 3)
9960 		    {
9961 		      /*3c68 */
9962 		      if (myCalib->black_shading[colour] != NULL)
9963 			{
9964 			  for (pos = myCalib->first_position - 1;
9965 			       pos < myCalib->shadinglength; pos++)
9966 			    {
9967 			      if (myCalib->black_shading[colour][pos] == 0)
9968 				shadata = myShadingBase;
9969 			      else
9970 				shadata =
9971 				  myfact /
9972 				  myCalib->black_shading[colour][pos];
9973 
9974 			      shadata =
9975 				min ((shadata * le7cc) / le7d8, 0xffc0);
9976 			      myCalib->black_shading[colour][pos] &= 0x3f;
9977 			      myCalib->black_shading[colour][pos] |=
9978 				shadata & 0xffc0;
9979 			    }
9980 			}
9981 		      else
9982 			break;
9983 		    }
9984 		  else
9985 		    {
9986 		      /*3ce3 */
9987 		      if (myCalib->white_shading[colour] != NULL)
9988 			{
9989 			  for (pos = 0; pos < myCalib->shadinglength; pos++)
9990 			    {
9991 			      if (myCalib->white_shading[colour][pos] == 0)
9992 				shadata = myShadingBase;
9993 			      else
9994 				shadata =
9995 				  myfact /
9996 				  myCalib->white_shading[colour][pos];
9997 
9998 			      shadata =
9999 				min ((shadata * le7cc) / le7d8, 0xffff);
10000 			      myCalib->white_shading[colour][pos] = shadata;
10001 			    }
10002 			}
10003 		      else
10004 			break;
10005 		    }
10006 		}
10007 	    }
10008 	}
10009 
10010       /*3d4c */
10011       memset (&calbuffers, 0, sizeof (struct st_cal2));
10012 
10013       /* If black shading correction is enabled ... */
10014       if ((Regs[0x1cf] & 8) != 0)
10015 	Shading_black_apply (dev, Regs, channels, myCalib, &calbuffers);
10016 
10017       /*3e6e */
10018 
10019       /* If white shading correction is enabled ... */
10020       if ((Regs[0x1cf] & 4) != 0)
10021 	Shading_white_apply (dev, Regs, channels, myCalib, &calbuffers);
10022 
10023       /* 3f74 */
10024       if (rst == 0)
10025 	{
10026 	  data_bitset (&Regs[0x60b], 0x40, lf9d0);		/*-x------*/
10027 	  data_bitset (&Regs[0x60b], 0x10, lf9d1);		/*---x----*/
10028 
10029 	  rst = Write_Byte (dev->usb_handle, 0xee0b, Regs[0x060b]);
10030 	}
10031     }
10032   /*3fb5 */
10033 
10034   DBG (DBG_FNC, "- Shading_apply: %i\n", rst);
10035 
10036   return rst;
10037 }
10038 
10039 static SANE_Int
Bulk_Operation(struct st_device * dev,SANE_Byte op,SANE_Int buffer_size,SANE_Byte * buffer,SANE_Int * transferred)10040 Bulk_Operation (struct st_device *dev, SANE_Byte op, SANE_Int buffer_size,
10041 		SANE_Byte * buffer, SANE_Int * transferred)
10042 {
10043   SANE_Int iTransferSize, iBytesToTransfer, iPos, rst, iBytesTransfered;
10044 
10045   DBG (DBG_FNC, "+ Bulk_Operation(op=%s, buffer_size=%i, buffer):\n",
10046        ((op & 0x01) != 0) ? "READ" : "WRITE", buffer_size);
10047 
10048   iBytesToTransfer = buffer_size;
10049   iPos = 0;
10050   rst = OK;
10051   iBytesTransfered = 0;
10052 
10053   if (transferred != NULL)
10054     *transferred = 0;
10055 
10056   iTransferSize = min (buffer_size, RTS_Debug->dmatransfersize);
10057 
10058   if (op != 0)
10059     {
10060       /* Lectura */
10061       do
10062 	{
10063 	  iTransferSize = min (iTransferSize, iBytesToTransfer);
10064 
10065 	  iBytesTransfered =
10066 	    Read_Bulk (dev->usb_handle, &buffer[iPos], iTransferSize);
10067 	  if (iBytesTransfered < 0)
10068 	    {
10069 	      rst = ERROR;
10070 	      break;
10071 	    }
10072 	  else
10073 	    {
10074 	      if (transferred != NULL)
10075 		*transferred += iBytesTransfered;
10076 	    }
10077 	  iPos += iTransferSize;
10078 	  iBytesToTransfer -= iTransferSize;
10079 	}
10080       while (iBytesToTransfer > 0);
10081     }
10082   else
10083     {
10084       /* Escritura */
10085       do
10086 	{
10087 	  iTransferSize = min (iTransferSize, iBytesToTransfer);
10088 
10089 	  if (Write_Bulk (dev->usb_handle, &buffer[iPos], iTransferSize) !=
10090 	      OK)
10091 	    {
10092 	      rst = ERROR;
10093 	      break;
10094 	    }
10095 	  else
10096 	    {
10097 	      if (transferred != NULL)
10098 		*transferred += iTransferSize;
10099 	    }
10100 	  iPos += iTransferSize;
10101 	  iBytesToTransfer -= iTransferSize;
10102 	}
10103       while (iBytesToTransfer > 0);
10104     }
10105 
10106   DBG (DBG_FNC, "- Bulk_Operation: %i\n", rst);
10107 
10108   return rst;
10109 }
10110 
10111 static SANE_Int
Reading_BufferSize_Notify(struct st_device * dev,SANE_Int data,SANE_Int size)10112 Reading_BufferSize_Notify (struct st_device *dev, SANE_Int data,
10113 			   SANE_Int size)
10114 {
10115   SANE_Int rst;
10116 
10117   DBG (DBG_FNC, "+ Reading_BufferSize_Notify(data=%i, size=%i):\n", data,
10118        size);
10119 
10120   rst = RTS_DMA_Enable_Read (dev, 0x0008, size, data);
10121 
10122   DBG (DBG_FNC, "- Reading_BufferSize_Notify: %i\n", rst);
10123 
10124   return rst;
10125 }
10126 
10127 static SANE_Int
Reading_Wait(struct st_device * dev,SANE_Byte Channels_per_dot,SANE_Byte Channel_size,SANE_Int size,SANE_Int * last_amount,SANE_Int seconds,SANE_Byte op)10128 Reading_Wait (struct st_device *dev, SANE_Byte Channels_per_dot,
10129 	      SANE_Byte Channel_size, SANE_Int size, SANE_Int * last_amount,
10130 	      SANE_Int seconds, SANE_Byte op)
10131 {
10132   SANE_Int rst;
10133   SANE_Byte cTimeout, executing;
10134   SANE_Int lastAmount, myAmount;
10135   long tick;
10136 
10137   DBG (DBG_FNC,
10138        "+ Reading_Wait(Channels_per_dot=%i, Channel_size=%i, size=%i, *last_amount, seconds=%i, op=%i):\n",
10139        Channels_per_dot, Channel_size, size, seconds, op);
10140 
10141   rst = OK;
10142   cTimeout = FALSE;
10143   lastAmount = 0;
10144 
10145   myAmount = Reading_BufferSize_Get (dev, Channels_per_dot, Channel_size);
10146   if (myAmount < size)
10147     {
10148       /* Wait until scanner fills its buffer */
10149       if (seconds == 0)
10150 	seconds = 10;
10151       tick = GetTickCount () + (seconds * 1000);
10152 
10153       while (cTimeout == FALSE)
10154 	{
10155 	  myAmount =
10156 	    Reading_BufferSize_Get (dev, Channels_per_dot, Channel_size);
10157 
10158 	  /* check special case */
10159 	  if (op == TRUE)
10160 	    {
10161 	      if (((myAmount + 0x450) > size)
10162 		  || (RTS_IsExecuting (dev, &executing) == FALSE))
10163 		break;
10164 	    }
10165 
10166 	  if (myAmount < size)
10167 	    {
10168 	      /* Check timeout */
10169 	      if (myAmount == lastAmount)
10170 		{
10171 		  /* we are in timeout? */
10172 		  if (tick < GetTickCount ())
10173 		    {
10174 		      /* TIMEOUT */
10175 		      rst = ERROR;
10176 		      cTimeout = TRUE;
10177 		    }
10178 		  else
10179 		    usleep (100 * 1000);
10180 		}
10181 	      else
10182 		{
10183 		  /* Amount increased, update tick */
10184 		  lastAmount = myAmount;
10185 		  tick = GetTickCount () + (seconds * 1000);
10186 		}
10187 	    }
10188 	  else
10189 	    {
10190 	      lastAmount = myAmount;
10191 	      break;		/* buffer full */
10192 	    }
10193 	}
10194     }
10195 
10196   if (last_amount != NULL)
10197     *last_amount = myAmount;
10198 
10199   DBG (DBG_FNC, "- Reading_Wait: %i , last_amount=%i\n", rst, myAmount);
10200 
10201   return rst;
10202 }
10203 
10204 static SANE_Int
RTS_GetImage_GetBuffer(struct st_device * dev,double dSize,char unsigned * buffer,double * transferred)10205 RTS_GetImage_GetBuffer (struct st_device *dev, double dSize,
10206 			char unsigned *buffer, double *transferred)
10207 {
10208   SANE_Int rst = ERROR;
10209   SANE_Int itransferred;
10210   double dtransferred = 0;
10211 
10212   DBG (DBG_FNC, "+ RTS_GetImage_GetBuffer(dSize=%f, buffer, transferred):\n",
10213        dSize);
10214 
10215   rst = OK;
10216   dSize /= 2;
10217 
10218   if (dSize > 0)
10219     {
10220       SANE_Int myLength;
10221       SANE_Int iPos = 0;
10222 
10223       do
10224 	{
10225 	  itransferred = 0;
10226 	  myLength =
10227 	    (dSize <=
10228 	     RTS_Debug->dmasetlength) ? dSize : RTS_Debug->dmasetlength;
10229 
10230 	  if (myLength > 0x1ffe0)
10231 	    myLength = 0x1ffe0;
10232 
10233 	  rst = ERROR;
10234 	  if (Reading_Wait (dev, 0, 1, myLength * 2, NULL, 5, FALSE) == OK)
10235 	    {
10236 	      if (Reading_BufferSize_Notify (dev, 0, myLength * 2) == OK)
10237 		rst =
10238 		  Bulk_Operation (dev, BLK_READ, myLength * 2, &buffer[iPos],
10239 				  &itransferred);
10240 	    }
10241 
10242 	  if (rst != OK)
10243 	    break;
10244 
10245 	  iPos += itransferred;
10246 	  dSize -= itransferred;
10247 	  dtransferred += itransferred * 2;
10248 	}
10249       while (dSize > 0);
10250     }
10251 
10252   /* Return bytes transferred */
10253   if (transferred != NULL)
10254     *transferred = dtransferred;
10255 
10256   if (rst != OK)
10257     RTS_DMA_Cancel (dev);
10258 
10259   DBG (DBG_FNC, "- RTS_GetImage_GetBuffer: %i\n", rst);
10260 
10261   return rst;
10262 }
10263 
10264 static SANE_Int
RTS_GetImage_Read(struct st_device * dev,SANE_Byte * buffer,struct st_scanparams * scancfg,struct st_hwdconfig * hwdcfg)10265 RTS_GetImage_Read (struct st_device *dev, SANE_Byte * buffer,
10266 		   struct st_scanparams *scancfg, struct st_hwdconfig *hwdcfg)
10267 {
10268   /*buffer   f80c = esp+14
10269      scancfg    f850 = esp+18
10270      hwdcfg faac = */
10271 
10272   SANE_Int rst = ERROR;
10273 
10274   DBG (DBG_FNC, "+ RTS_GetImage_Read(buffer, scancfg, hwdcfg):\n");
10275 
10276   if (buffer != NULL)
10277     {
10278       double dSize = scancfg->bytesperline * scancfg->coord.height;
10279       SANE_Byte exfn;
10280 
10281       if (scancfg->depth == 12)
10282 	dSize = (dSize * 3) / 4;
10283 
10284       /*3ff6 */
10285       exfn = 1;
10286       if (hwdcfg != NULL)
10287 	if (hwdcfg->compression != FALSE)
10288 	  exfn = 0;
10289 
10290       if (exfn != 0)
10291 	{
10292 	  double transferred;
10293 	  rst = RTS_GetImage_GetBuffer (dev, dSize, buffer, &transferred);
10294 	}
10295 
10296       if (rst == OK)
10297 	RTS_WaitScanEnd (dev, 1500);
10298     }
10299 
10300   DBG (DBG_FNC, "- RTS_GetImage_Read: %i\n", rst);
10301 
10302   return rst;
10303 }
10304 
10305 static SANE_Int
RTS_GetImage(struct st_device * dev,SANE_Byte * Regs,struct st_scanparams * scancfg,struct st_gain_offset * gain_offset,SANE_Byte * buffer,struct st_calibration * myCalib,SANE_Int options,SANE_Int gaincontrol)10306 RTS_GetImage (struct st_device *dev, SANE_Byte * Regs,
10307 	      struct st_scanparams *scancfg,
10308 	      struct st_gain_offset *gain_offset, SANE_Byte * buffer,
10309 	      struct st_calibration *myCalib, SANE_Int options,
10310 	      SANE_Int gaincontrol)
10311 {
10312   /* 42b8e10 */
10313 
10314   SANE_Int rst = ERROR;		/* default */
10315 
10316   DBG (DBG_FNC,
10317        "+ RTS_GetImage(*Regs, *scancfg, *gain_offset, *buffer, myCalib, options=0x%08x, gaincontrol=%i):\n",
10318        options, gaincontrol);
10319   dbg_ScanParams (scancfg);
10320 
10321   /* validate arguments */
10322   if ((Regs != NULL) && (scancfg != NULL))
10323     {
10324       if ((scancfg->coord.width != 0) && (scancfg->coord.height != 0))
10325 	{
10326 	  struct st_scanparams *myscancfg;
10327 
10328 	  /* let's make a copy of scan config */
10329 	  myscancfg =
10330 	    (struct st_scanparams *) malloc (sizeof (struct st_scanparams));
10331 	  if (myscancfg != NULL)
10332 	    {
10333 	      struct st_hwdconfig *hwdcfg;
10334 
10335 	      memcpy (myscancfg, scancfg, sizeof (struct st_scanparams));
10336 
10337 	      /* Allocate space for low level config */
10338 	      hwdcfg =
10339 		(struct st_hwdconfig *) malloc (sizeof (struct st_hwdconfig));
10340 	      if (hwdcfg != NULL)
10341 		{
10342 		  memset (hwdcfg, 0, sizeof (struct st_hwdconfig));
10343 
10344 		  if (((options & 2) != 0) || ((_B1 (options) & 1) != 0))
10345 		    {
10346 		      /* switch off lamp */
10347 		      data_bitset (&Regs[0x146], 0x40, 0);
10348 
10349 		      Write_Byte (dev->usb_handle, 0xe946, Regs[0x146]);
10350 		      usleep (1000 * ((v14b4 == 0) ? 500 : 300));
10351 		    }
10352 
10353 		  hwdcfg->scantype = scan.scantype;
10354 		  hwdcfg->use_gamma_tables =
10355 		    ((options & OP_USE_GAMMA) != 0) ? 1 : 0;
10356 		  hwdcfg->white_shading =
10357 		    ((options & OP_WHITE_SHAD) != 0) ? 1 : 0;
10358 		  hwdcfg->black_shading =
10359 		    ((options & OP_BLACK_SHAD) != 0) ? 1 : 0;
10360 		  hwdcfg->motor_direction =
10361 		    ((options & OP_BACKWARD) !=
10362 		     0) ? MTR_BACKWARD : MTR_FORWARD;
10363 		  hwdcfg->compression =
10364 		    ((options & OP_COMPRESSION) != 0) ? 1 : 0;
10365 		  hwdcfg->static_head =
10366 		    ((options & OP_STATIC_HEAD) != 0) ? 1 : 0;
10367 		  hwdcfg->dummy_scan = (buffer == NULL) ? TRUE : FALSE;
10368 		  hwdcfg->arrangeline = 0;
10369 		  hwdcfg->highresolution =
10370 		    (myscancfg->resolution_x > 1200) ? TRUE : FALSE;
10371 		  hwdcfg->unk3 = 0;
10372 
10373 		  /* Set Left coord */
10374 		  myscancfg->coord.left +=
10375 		    ((dev->sensorcfg->type == CCD_SENSOR) ? 24 : 50);
10376 
10377 		  switch (myscancfg->resolution_x)
10378 		    {
10379 		    case 1200:
10380 		      myscancfg->coord.left -= 63;
10381 		      break;
10382 		    case 2400:
10383 		      myscancfg->coord.left -= 126;
10384 		      break;
10385 		    }
10386 
10387 		  if (myscancfg->coord.left < 0)
10388 		    myscancfg->coord.left = 0;
10389 
10390 		  RTS_Setup (dev, Regs, myscancfg, hwdcfg, gain_offset);
10391 
10392 		  /* Setting exposure time */
10393 		  switch (scan.scantype)
10394 		    {
10395 		    case ST_NORMAL:
10396 		      if (scan.resolution_x == 100)
10397 			{
10398 			  SANE_Int iValue;
10399 			  SANE_Byte *myRegs;
10400 
10401 			  myRegs =
10402 			    (SANE_Byte *) malloc (RT_BUFFER_LEN *
10403 						  sizeof (SANE_Byte));
10404 			  if (myRegs != NULL)
10405 			    {
10406 			      memset (myRegs, 0,
10407 				     RT_BUFFER_LEN * sizeof (SANE_Byte));
10408 			      RTS_Setup (dev, myRegs, &scan, hwdcfg,
10409 					 gain_offset);
10410 
10411 			      iValue = data_lsb_get (&myRegs[0x30], 3);
10412 			      data_lsb_set (&Regs[0x30], iValue, 3);
10413 
10414 			      /*Copy myregisters mexpts to Regs mexpts */
10415 			      iValue = data_lsb_get (&myRegs[0x33], 3);
10416 			      data_lsb_set (&Regs[0x33], iValue, 3);
10417 
10418 			      iValue = data_lsb_get (&myRegs[0x39], 3);
10419 			      data_lsb_set (&Regs[0x39], iValue, 3);
10420 
10421 			      iValue = data_lsb_get (&myRegs[0x3f], 3);
10422 			      data_lsb_set (&Regs[0x3f], iValue, 3);
10423 
10424 			      free (myRegs);
10425 			    }
10426 			}
10427 		      break;
10428 		    case ST_NEG:
10429 		      {
10430 			SANE_Int myvalue;
10431 
10432 			/* Setting exposure times for Negative scans */
10433 			data_lsb_set (&Regs[0x30], myscancfg->expt, 3);
10434 			data_lsb_set (&Regs[0x33], myscancfg->expt, 3);
10435 			data_lsb_set (&Regs[0x39], myscancfg->expt, 3);
10436 			data_lsb_set (&Regs[0x3f], myscancfg->expt, 3);
10437 
10438 			data_lsb_set (&Regs[0x36], 0, 3);
10439 			data_lsb_set (&Regs[0x3c], 0, 3);
10440 			data_lsb_set (&Regs[0x42], 0, 3);
10441 
10442 			myvalue =
10443 			  ((myscancfg->expt +
10444 			    1) / (data_lsb_get (&Regs[0xe0], 1) + 1)) - 1;
10445 			data_lsb_set (&Regs[0xe1], myvalue, 3);
10446 		      }
10447 		      break;
10448 		    }
10449 
10450 		  /* 91a0 */
10451 		  if (myscancfg->resolution_y > 600)
10452 		    {
10453 		      options |= 0x20000000;
10454 		      if (options != 0)	/* Always true ... */
10455 			SetMultiExposure (dev, Regs);
10456 		      else
10457 			myscancfg->coord.top += hwdcfg->startpos;
10458 		    }
10459 		  else
10460 		    SetMultiExposure (dev, Regs);
10461 
10462 		  /* 91e2 */
10463 		  RTS_WriteRegs (dev->usb_handle, Regs);
10464 		  if (myCalib != NULL)
10465 		    Shading_apply (dev, Regs, myscancfg, myCalib);
10466 
10467 		  if (dev->motorcfg->changemotorcurrent != FALSE)
10468 		    Motor_Change (dev, Regs,
10469 				  Motor_GetFromResolution (myscancfg->
10470 							   resolution_x));
10471 
10472 		  /* mlock = 0 */
10473 		  data_bitset (&Regs[0x00], 0x10, 0);
10474 
10475 		  data_wide_bitset (&Regs[0xde], 0xfff, 0);
10476 
10477 		  /* release motor */
10478 		  Motor_Release (dev);
10479 
10480 		  if (RTS_Warm_Reset (dev) == OK)
10481 		    {
10482 		      rst = OK;
10483 
10484 		      SetLock (dev->usb_handle, Regs,
10485 			       (myscancfg->depth == 16) ? FALSE : TRUE);
10486 
10487 		      /* set gain control */
10488 		      Lamp_SetGainMode (dev, Regs, myscancfg->resolution_x,
10489 					gaincontrol);
10490 
10491 		      /* send registers to scanner */
10492 		      if (RTS_WriteRegs (dev->usb_handle, Regs) == OK)
10493 			{
10494 			  /* execute! */
10495 			  if (RTS_Execute (dev) == OK)
10496 			    RTS_GetImage_Read (dev, buffer, myscancfg, hwdcfg);	/*92e7 */
10497 			}
10498 
10499 		      /*92fc */
10500 		      SetLock (dev->usb_handle, Regs, FALSE);
10501 
10502 		      if ((options & 0x200) != 0)
10503 			{
10504 			  /* switch on lamp */
10505 			  data_bitset (&Regs[0x146], 0x40, 1);
10506 
10507 			  Write_Byte (dev->usb_handle, 0xe946, Regs[0x146]);
10508 			  /* Wait 3 seconds */
10509 			  usleep (1000 * 3000);
10510 			}
10511 
10512 		      /*9351 */
10513 		      if (dev->motorcfg->changemotorcurrent == TRUE)
10514 			Motor_Change (dev, dev->init_regs, 3);
10515 		    }
10516 
10517 		  /* free low level configuration */
10518 		  free (hwdcfg);
10519 		}
10520 
10521 	      /* free scanning configuration */
10522 	      free (myscancfg);
10523 	    }
10524 	}
10525     }
10526 
10527   DBG (DBG_FNC, "- RTS_GetImage: %i\n", rst);
10528 
10529   return rst;
10530 }
10531 
10532 static SANE_Int
Refs_Detect(struct st_device * dev,SANE_Byte * Regs,SANE_Int resolution_x,SANE_Int resolution_y,SANE_Int * x,SANE_Int * y)10533 Refs_Detect (struct st_device *dev, SANE_Byte * Regs, SANE_Int resolution_x,
10534 	     SANE_Int resolution_y, SANE_Int * x, SANE_Int * y)
10535 {
10536   SANE_Int rst = ERROR;		/* default */
10537 
10538   DBG (DBG_FNC, "+ Refs_Detect(*Regs, resolution_x=%i, resolution_y=%i):\n",
10539        resolution_x, resolution_y);
10540 
10541   if ((x != NULL) && (y != NULL))
10542     {
10543       SANE_Byte *image;
10544       struct st_scanparams scancfg;
10545 
10546       *x = *y = 0;		/* default */
10547 
10548       /* set configuration to scan a little area at the top-left corner */
10549       memset (&scancfg, 0, sizeof (struct st_scanparams));
10550       scancfg.depth = 8;
10551       scancfg.colormode = CM_GRAY;
10552       scancfg.channel = CL_RED;
10553       scancfg.resolution_x = resolution_x;
10554       scancfg.resolution_y = resolution_y;
10555       scancfg.coord.left = 4;
10556       scancfg.coord.width = (resolution_x * 3) / 10;
10557       scancfg.coord.top = 1;
10558       scancfg.coord.height = (resolution_y * 4) / 10;
10559       scancfg.shadinglength = (resolution_x * 17) / 2;
10560       scancfg.bytesperline = scancfg.coord.width;
10561 
10562       /* allocate space to store image */
10563       image =
10564 	(SANE_Byte *) malloc ((scancfg.coord.height * scancfg.coord.width) *
10565 			      sizeof (SANE_Byte));
10566       if (image != NULL)
10567 	{
10568 	  struct st_gain_offset gain_offset;
10569 	  SANE_Int gaincontrol, pwmlamplevel_backup, C;
10570 
10571 	  gaincontrol = 0;
10572 	  if (RTS_Debug->use_fixed_pwm == FALSE)
10573 	    {
10574 	      /* 3877 */
10575 	      gaincontrol = Lamp_GetGainMode (dev, resolution_x, ST_NORMAL);	/* scan.scantype */
10576 	      pwmlamplevel = 0;
10577 	      Lamp_PWM_use (dev, 1);
10578 	      Lamp_PWM_DutyCycle_Set (dev, (gaincontrol == 0) ? 0x12 : 0x26);
10579 
10580 	      /* Enciende flb lamp */
10581 	      Lamp_Status_Set (dev, NULL, TRUE, FLB_LAMP);
10582 	      usleep (1000 * 2000);
10583 	    }
10584 
10585 	  /* 38d6 */
10586 	  pwmlamplevel_backup = pwmlamplevel;
10587 	  pwmlamplevel = 0;
10588 	  Lamp_PWM_use (dev, 1);
10589 
10590 	  memset (&gain_offset, 0, sizeof (struct st_gain_offset));
10591 	  for (C = CL_RED; C <= CL_BLUE; C++)
10592 	    {
10593 	      gain_offset.pag[C] = 3;
10594 	      gain_offset.vgag1[C] = 4;
10595 	      gain_offset.vgag2[C] = 4;
10596 	    }
10597 
10598 	  /* perform lamp warmup */
10599 	  Lamp_Warmup (dev, Regs, FLB_LAMP, resolution_x);
10600 
10601 	  /* retrieve image from scanner */
10602 	  if (RTS_GetImage
10603 	      (dev, Regs, &scancfg, &gain_offset, image, 0, 0x20000000,
10604 	       gaincontrol) == OK)
10605 	    {
10606 	      SANE_Int ser1, ler1;
10607 
10608 	      /* same image to disk if required by user */
10609 	      if (RTS_Debug->SaveCalibFile != FALSE)
10610 		{
10611 		  dbg_tiff_save ("pre-autoref.tiff",
10612 				 scancfg.coord.width,
10613 				 scancfg.coord.height,
10614 				 scancfg.depth,
10615 				 CM_GRAY,
10616 				 scancfg.resolution_x,
10617 				 scancfg.resolution_y,
10618 				 image,
10619 				 scancfg.coord.height * scancfg.coord.width);
10620 		}
10621 
10622 	      /* calculate reference position */
10623 	      if (Refs_Analyze_Pattern (&scancfg, image, &ler1, 1, &ser1, 0)
10624 		  == OK)
10625 		{
10626 		  *y = scancfg.coord.top + ler1;
10627 		  *x = scancfg.coord.left + ser1;
10628 
10629 		  rst = OK;
10630 		}
10631 	    }
10632 
10633 	  free (image);
10634 
10635 	  pwmlamplevel = pwmlamplevel_backup;
10636 	}
10637 
10638       DBG (DBG_FNC, " -> Detected refs: x=%i , y=%i\n", *x, *y);
10639     }
10640 
10641   DBG (DBG_FNC, "- Refs_Detect: %i\n", rst);
10642 
10643   return rst;
10644 }
10645 
10646 static SANE_Int
Refs_Set(struct st_device * dev,SANE_Byte * Regs,struct st_scanparams * scancfg)10647 Refs_Set (struct st_device *dev, SANE_Byte * Regs,
10648 	  struct st_scanparams *scancfg)
10649 {
10650   SANE_Int rst;
10651   SANE_Int y, x;
10652   struct st_autoref refcfg;
10653 
10654   DBG (DBG_FNC, "+ Refs_Set(*Regs, *scancfg):\n");
10655   dbg_ScanParams (scancfg);
10656 
10657   rst = OK;
10658 
10659   /* get fixed references for given resolution */
10660   cfg_vrefs_get (dev->sensorcfg->type, scancfg->resolution_x, &scan.ler,
10661 		 &scan.ser);
10662   scan.leftleading = scan.ser;
10663   scan.startpos = scan.ler;
10664 
10665   /* get auto reference configuration */
10666   cfg_autoref_get (&refcfg);
10667 
10668   if (refcfg.type != REF_NONE)
10669     {
10670       /* if reference counter is == 0 perform auto detection */
10671       if (Refs_Counter_Load (dev) == 0)
10672 	{
10673 	  DBG (DBG_FNC,
10674 	       " -> Refs_Set - Autodetection mandatory (counter == 0)\n");
10675 
10676 	  refcfg.type = REF_AUTODETECT;
10677 	}
10678 
10679       switch (refcfg.type)
10680 	{
10681 	case REF_AUTODETECT:
10682 	  /* try to autodetect references scanning a little area */
10683 	  if (Refs_Detect
10684 	      (dev, Regs, refcfg.resolution, refcfg.resolution, &x, &y) == OK)
10685 	    Refs_Save (dev, x, y);
10686 	  else
10687 	    rst = ERROR;
10688 
10689 	  Head_ParkHome (dev, TRUE, dev->motorcfg->parkhomemotormove);
10690 	  break;
10691 
10692 	case REF_TAKEFROMSCANNER:
10693 	  /* Try to get values from scanner */
10694 	  if (Refs_Load (dev, &x, &y) == ERROR)
10695 	    {
10696 	      if (Refs_Detect
10697 		  (dev, Regs, refcfg.resolution, refcfg.resolution, &x,
10698 		   &y) == OK)
10699 		Refs_Save (dev, x, y);
10700 	      else
10701 		rst = ERROR;
10702 
10703 	      Head_ParkHome (dev, TRUE, dev->motorcfg->parkhomemotormove);
10704 	    }
10705 	  break;
10706 	}
10707 
10708       if (rst == OK)
10709 	{
10710 	  /* values are based on resolution given by refcfg.resolution.
10711 
10712 	     offset_x and y are based on 2400 dpi so convert values to that dpi
10713 	     before adding offsets and then return to resolution given by user */
10714 
10715 	  x *= (2400 / refcfg.resolution);
10716 	  y *= (2400 / refcfg.resolution);
10717 
10718 	  scan.leftleading = x;
10719 	  scan.startpos = y;
10720 	  scan.ser = ((x + refcfg.offset_x) * scancfg->resolution_x) / 2400;
10721 	  scan.ler = ((y + refcfg.offset_y) * scancfg->resolution_y) / 2400;
10722 
10723 	  DBG (DBG_FNC,
10724 	       " -> After SEROffset and LEROffset, xoffset = %i, yoffset =%i\n",
10725 	       scan.ser, scan.ler);
10726 	}
10727 
10728       /* increase refs counter */
10729       Refs_Counter_Inc (dev);
10730     }
10731 
10732   DBG (DBG_FNC, "- Refs_Set: %i\n", rst);
10733 
10734   return rst;
10735 }
10736 
10737 static SANE_Int
Lamp_Status_Set(struct st_device * dev,SANE_Byte * Regs,SANE_Int turn_on,SANE_Int lamp)10738 Lamp_Status_Set (struct st_device *dev, SANE_Byte * Regs, SANE_Int turn_on,
10739 		 SANE_Int lamp)
10740 {
10741   SANE_Int rst = ERROR;		/* default */
10742   SANE_Byte freevar = FALSE;
10743 
10744   DBG (DBG_FNC, "+ Lamp_Status_Set(*Regs, turn_on=%i->%s, lamp=%s)\n",
10745        turn_on,
10746        ((((lamp - 1) | turn_on) & 1) == 1) ? "Yes" : "No",
10747        (lamp == FLB_LAMP) ? "FLB_LAMP" : "TMA_LAMP");
10748 
10749   if (Regs == NULL)
10750     {
10751       Regs = (SANE_Byte *) malloc (RT_BUFFER_LEN * sizeof (SANE_Byte));
10752 
10753       if (Regs != NULL)
10754 	freevar = TRUE;
10755     }
10756 
10757   if (Regs != NULL)
10758     {
10759       RTS_ReadRegs (dev->usb_handle, Regs);
10760 
10761       /* next op depends on chipset */
10762       switch (dev->chipset->model)
10763 	{
10764 	case RTS8822BL_03A:
10765 	  /* register 0xe946 has 2 bits and each one refers one lamp
10766 	     0x40: FLB_LAMP | 0x20 : TMA_LAMP
10767 	     if both were enabled both lamps would be switched on */
10768 	  data_bitset (&Regs[0x146], 0x20, ((lamp == TMA_LAMP) && (turn_on == TRUE)) ? 1 : 0);	/* TMA */
10769 	  data_bitset (&Regs[0x146], 0x40, ((lamp == FLB_LAMP) && (turn_on == TRUE)) ? 1 : 0);	/* FLB */
10770 
10771 	  data_bitset (&Regs[0x155], 0x10, (lamp != FLB_LAMP) ? 1 : 0);
10772 	  break;
10773 	default:
10774 	  /* the other chipsets only use one bit to indicate when a lamp is
10775 	     switched on or not being bit 0x10 in 0xe955 who decides which lamp
10776 	     is affected */
10777 	  /* switch on lamp? yes if TMA_LAMP, else whatever turn_on says */
10778 	  data_bitset (&Regs[0x146], 0x40, ((lamp - 1) | turn_on));
10779 	  /* what lamp must be switched on? */
10780 	  if ((Regs[0x146] & 0x40) != 0)
10781 	    data_bitset (&Regs[0x155], 0x10, (lamp != FLB_LAMP) ? 1 : 0);
10782 	  break;
10783 	}
10784 
10785       /*42b8cd1 */
10786       /* switch on/off lamp */
10787       /*dev->init_regs[0x0146] = (dev->init_regs[0x146] & 0xbf) | (Regs[0x146] & 0x40); */
10788       dev->init_regs[0x0146] = (dev->init_regs[0x146] & 0x9f) | (Regs[0x146] & 0x60);		/*-xx-----*/
10789 
10790       /* Which lamp */
10791       dev->init_regs[0x0155] = Regs[0x0155];
10792       Write_Byte (dev->usb_handle, 0xe946, Regs[0x0146]);
10793       usleep (1000 * 200);
10794       Write_Buffer (dev->usb_handle, 0xe954, &Regs[0x0154], 2);
10795     }
10796 
10797   if (freevar != FALSE)
10798     {
10799       free (Regs);
10800       Regs = NULL;
10801     }
10802 
10803   DBG (DBG_FNC, "- Lamp_Status_Set: %i\n", rst);
10804 
10805   return rst;
10806 }
10807 
10808 static SANE_Int
Get_PAG_Value(SANE_Byte scantype,SANE_Byte color)10809 Get_PAG_Value (SANE_Byte scantype, SANE_Byte color)
10810 {
10811   SANE_Int rst, iType, iColor;
10812 
10813   switch (scantype)
10814     {
10815     case ST_NEG:
10816       iType = CALIBNEGATIVEFILM;
10817       break;
10818     case ST_TA:
10819       iType = CALIBTRANSPARENT;
10820       break;
10821     case ST_NORMAL:
10822       iType = CALIBREFLECTIVE;
10823       break;
10824     default:
10825       iType = CALIBREFLECTIVE;
10826       break;
10827     }
10828 
10829   switch (color)
10830     {
10831     case CL_BLUE:
10832       iColor = PAGB;
10833       break;
10834     case CL_GREEN:
10835       iColor = PAGG;
10836       break;
10837     case CL_RED:
10838       iColor = PAGR;
10839       break;
10840     default:
10841       iColor = PAGR;
10842       break;
10843     }
10844 
10845   rst = get_value (iType, iColor, 1, FITCALIBRATE);
10846 
10847   DBG (DBG_FNC, "> Get_PAG_Value(scantype=%s, color=%i): %i\n",
10848        dbg_scantype (scantype), color, rst);
10849 
10850   return rst;
10851 }
10852 
10853 static SANE_Byte
Lamp_GetGainMode(struct st_device * dev,SANE_Int resolution,SANE_Byte scantype)10854 Lamp_GetGainMode (struct st_device *dev, SANE_Int resolution,
10855 		  SANE_Byte scantype)
10856 {
10857   SANE_Byte ret;
10858   SANE_Int mygain, iValue;
10859 
10860   switch (scantype)
10861     {
10862     case ST_TA:
10863       ret = 0;
10864       iValue = DPIGAINCONTROL_TA600;
10865       break;
10866     case ST_NEG:
10867       ret = 1;
10868       iValue = DPIGAINCONTROL_NEG600;
10869       break;
10870     default:			/* Reflective */
10871       ret = 1;
10872       iValue = DPIGAINCONTROL600;
10873       break;
10874     }
10875 
10876   mygain = get_value (SCAN_PARAM, iValue, ret, usbfile);
10877   ret = 0;
10878 
10879 /*
10880 
10881 */
10882   if (scantype == ST_NORMAL)
10883     {
10884       if (dev->chipset->model == RTS8822L_02A)
10885 	{
10886 	  switch (resolution)
10887 	    {
10888 	    case 100:
10889 	    case 150:
10890 	    case 300:
10891 	    case 600:
10892 	    case 1200:
10893 	    case 2400:
10894 	    case 4800:
10895 	      ret = ((RTS_Debug->usbtype != USB11) && (mygain != 0)) ? 1 : 0;
10896 	      break;
10897 	    }
10898 	}
10899       else
10900 	{
10901 	  switch (resolution)
10902 	    {
10903 	    case 100:
10904 	    case 200:
10905 	    case 300:
10906 	    case 600:
10907 	      if (RTS_Debug->usbtype != USB11)
10908 		ret = (mygain != 0) ? 1 : 0;
10909 	      else
10910 		ret = (resolution == 100) ? 1 : 0;
10911 	      break;
10912 	    case 1200:
10913 	    case 2400:
10914 	      ret = 0;
10915 	      break;
10916 	    }
10917 	}
10918     }
10919   else if (scantype == ST_TA)
10920     {
10921       switch (resolution)
10922 	{
10923 	  /*hp3970 */
10924 	case 100:
10925 	case 200:
10926 	  /*common */
10927 	case 300:
10928 	case 600:
10929 	case 1200:
10930 	case 2400:
10931 	  /*hp4370 */
10932 	case 150:
10933 	case 4800:
10934 	  ret = ((RTS_Debug->usbtype != USB11) && (mygain != 0)) ? 1 : 0;
10935 	  break;
10936 	}
10937     }
10938   else
10939     {
10940       /* ST_NEG */
10941       switch (resolution)
10942 	{
10943 	case 100:
10944 	case 200:
10945 	case 300:
10946 	case 600:
10947 	  ret = ((RTS_Debug->usbtype != USB11) && (mygain != 0)) ? 1 : 0;
10948 	  break;
10949 	case 1200:
10950 	case 2400:
10951 	case 4800:		/*hp4370 */
10952 	  ret = 0;
10953 	  break;
10954 	}
10955     }
10956 
10957   DBG (DBG_FNC, "> Lamp_GetGainMode(resolution=%i, scantype=%s): %i\n",
10958        resolution, dbg_scantype (scantype), ret);
10959 
10960   return ret;
10961 }
10962 
10963 static SANE_Int
GetOneLineInfo(struct st_device * dev,SANE_Int resolution,SANE_Int * maximus,SANE_Int * minimus,double * average)10964 GetOneLineInfo (struct st_device *dev, SANE_Int resolution,
10965 		SANE_Int * maximus, SANE_Int * minimus, double *average)
10966 {
10967   SANE_Int rst = ERROR;
10968 
10969   DBG (DBG_FNC,
10970        "+ GetOneLineInfo(resolution=%i, *maximus, *minimus, *average):\n",
10971        resolution);
10972 
10973   /* Check parameters */
10974   if ((maximus != NULL) && (minimus != NULL) && (average != NULL))
10975     {
10976       SANE_Byte *Regs, *image;
10977       SANE_Int a, gainmode;
10978       struct st_gain_offset gain_offset;
10979       struct st_scanparams scancfg;
10980 
10981       Regs = (SANE_Byte *) malloc (RT_BUFFER_LEN * sizeof (SANE_Byte));
10982       if (Regs != NULL)
10983 	{
10984 	  /* Copy scanner registers */
10985 	  memcpy (Regs, dev->init_regs, RT_BUFFER_LEN * sizeof (SANE_Byte));
10986 
10987 	  /* Setting some registers */
10988 	  for (a = 0x192; a <= 0x19d; a++)
10989 	    Regs[a] = 0;
10990 
10991 	  /* Create calibration table */
10992 	  for (a = CL_RED; a <= CL_BLUE; a++)
10993 	    {
10994 	      gain_offset.edcg1[a] = 256;
10995 	      gain_offset.edcg2[a] = 0;
10996 	      gain_offset.odcg1[a] = 256;
10997 	      gain_offset.odcg2[a] = 0;
10998 	      gain_offset.vgag1[a] = 4;
10999 	      gain_offset.vgag2[a] = 4;
11000 	      gain_offset.pag[a] = Get_PAG_Value (scan.scantype, a);
11001 	    }
11002 
11003 	  RTS_GetScanmode (dev, scantype, 0, resolution);
11004 
11005 	  /* Setting scanning params */
11006 	  memset (&scancfg, 0, sizeof (struct st_scanparams));
11007 	  scancfg.colormode = CM_COLOR;
11008 	  scancfg.resolution_x = resolution;
11009 	  scancfg.resolution_y = resolution;
11010 	  scancfg.coord.left = 100;
11011 	  scancfg.coord.width = (resolution * 8.5) - 100;
11012 	  scancfg.coord.top = 1;
11013 	  scancfg.coord.height = 1;
11014 	  scancfg.depth = 8;
11015 	  scancfg.shadinglength = resolution * 8.5;
11016 	  scancfg.v157c = scancfg.coord.width * 3;
11017 	  scancfg.bytesperline = scancfg.v157c;
11018 
11019 	  /* Reserve buffer for line */
11020 	  image =
11021 	    (SANE_Byte *) malloc (((scancfg.coord.width * 0x21) * 3) *
11022 				  sizeof (SANE_Byte));
11023 	  if (image != NULL)
11024 	    {
11025 	      gainmode =
11026 		Lamp_GetGainMode (dev, resolution & 0xffff, scan.scantype);
11027 	      if (RTS_GetImage
11028 		  (dev, Regs, &scancfg, &gain_offset, image, 0,
11029 		   OP_STATIC_HEAD, gainmode) != ERROR)
11030 		{
11031 		  /* Read all image to take max min and average colours */
11032 		  SANE_Byte *pointer1 = image;
11033 		  SANE_Byte *pointer2;
11034 		  SANE_Byte *pointer3;
11035 		  SANE_Int cmin[3];	/* min values */
11036 		  SANE_Int cmax[3];	/* max values */
11037 		  double cave[3];	/* average values */
11038 		  SANE_Int mysize;
11039 
11040 		  if (scancfg.colormode != CM_GRAY)
11041 		    {
11042 		      pointer2 = image;
11043 		      pointer3 = image;
11044 		    }
11045 		  else
11046 		    {
11047 		      pointer2 = image + 1;
11048 		      pointer3 = image + 2;
11049 		    }
11050 
11051 		  for (a = CL_RED; a <= CL_BLUE; a++)
11052 		    {
11053 		      cmin[a] = 255;
11054 		      cmax[a] = 0;
11055 		      cave[a] = 0;
11056 		    }
11057 
11058 		  if (scancfg.coord.height > 0)
11059 		    {
11060 		      SANE_Int y, x;
11061 		      SANE_Byte *mypointer;
11062 		      SANE_Byte color;
11063 		      SANE_Int desp[3];
11064 
11065 		      desp[CL_RED] = pointer1 - pointer3;
11066 		      desp[CL_GREEN] = pointer2 - pointer3;
11067 		      desp[CL_BLUE] = 0;
11068 
11069 		      for (y = 0; y < scancfg.coord.height; y++)
11070 			{
11071 			  if (scancfg.coord.width > 0)
11072 			    {
11073 			      mypointer = pointer3;
11074 
11075 			      for (x = 0; x < scancfg.coord.width; x++)
11076 				{
11077 				  for (a = CL_RED; a <= CL_BLUE; a++)
11078 				    {
11079 				      /* Take colour values */
11080 				      color = *(mypointer + desp[a]);
11081 
11082 				      /* Take max values for each color */
11083 				      cmax[a] = max (cmax[a], color);
11084 
11085 				      /* Take min values for each color */
11086 				      cmin[a] = min (cmin[a], color);
11087 
11088 				      /* Average */
11089 				      cave[a] += color;
11090 				    }
11091 
11092 				  mypointer += 3;
11093 				}
11094 			    }
11095 
11096 			  /* point to the pixel that is below */
11097 			  pointer1 += scancfg.coord.width * 3;
11098 			  pointer2 += scancfg.coord.width * 3;
11099 			  pointer3 += scancfg.coord.width * 3;
11100 			}
11101 		    }
11102 
11103 		  mysize = scancfg.coord.height * scancfg.coord.width;
11104 		  if (mysize < 1)
11105 		    mysize = 1;
11106 
11107 		  for (a = CL_RED; a <= CL_BLUE; a++)
11108 		    {
11109 		      maximus[a] = cmax[a];
11110 		      minimus[a] = cmin[a];
11111 		      average[a] = cave[a] / mysize;
11112 		    }
11113 
11114 		  DBG (DBG_FNC, " -> GetOneLineInfo: max r=%3i g=%3i b=%3i\n",
11115 		       maximus[CL_RED], maximus[CL_GREEN], maximus[CL_BLUE]);
11116 		  DBG (DBG_FNC, " ->                 min r=%3i g=%3i b=%3i\n",
11117 		       minimus[CL_RED], minimus[CL_GREEN], minimus[CL_BLUE]);
11118 		  DBG (DBG_FNC,
11119 		       " ->                 avg r=%3.0f g=%3.0f b=%3.0f\n",
11120 		       average[CL_RED], average[CL_GREEN], average[CL_BLUE]);
11121 
11122 		  rst = OK;
11123 		}
11124 
11125 	      free (image);
11126 	    }
11127 
11128 	  free (Regs);
11129 	}
11130     }
11131 
11132   DBG (DBG_FNC, "- GetOneLineInfo: %i\n", rst);
11133 
11134   return OK;
11135 }
11136 
11137 static SANE_Int
Lamp_PWM_CheckStable(struct st_device * dev,SANE_Int resolution,SANE_Int lamp)11138 Lamp_PWM_CheckStable (struct st_device *dev, SANE_Int resolution,
11139 		      SANE_Int lamp)
11140 {
11141   struct st_checkstable check;
11142   SANE_Int rst;
11143 
11144   DBG (DBG_FNC, "+ Lamp_PWM_CheckStable(resolution=%i, lamp=%i):\n",
11145        resolution, lamp);
11146 
11147   rst = cfg_checkstable_get (lamp, &check);
11148 
11149   if (rst == OK)
11150     {
11151       SANE_Int maximus[3] = { 0 };
11152       SANE_Int minimus[3] = { 0 };
11153       double average[3] = { 0 };
11154       SANE_Int maxbigger;
11155       SANE_Int last_colour = 0;
11156 
11157       double diff = check.diff * 0.01;
11158       long tottime = GetTickCount () + check.tottime;
11159 
11160       while (GetTickCount () <= tottime)
11161 	{
11162 	  rst = GetOneLineInfo (dev, resolution, maximus, minimus, average);
11163 	  if (rst == OK)
11164 	    {
11165 	      /* Takes maximal colour value */
11166 	      maxbigger =
11167 		max (maximus[CL_GREEN],
11168 		     max (maximus[CL_BLUE], maximus[CL_RED]));
11169 
11170 	      /*breaks when colour intensity increases 'diff' or lower */
11171 	      if (abs (maxbigger - last_colour) < diff)
11172 		{
11173 		  DBG (DBG_FNC, " -> PWM is ready\n");
11174 		  break;
11175 		}
11176 
11177 	      last_colour = maxbigger;
11178 	    }
11179 
11180 	  usleep (1000 * check.interval);
11181 	}
11182 
11183     }
11184 
11185   DBG (DBG_FNC, "- Lamp_PWM_CheckStable: %i\n", rst);
11186 
11187   return OK;
11188 }
11189 
11190 static SANE_Byte
Refs_Counter_Load(struct st_device * dev)11191 Refs_Counter_Load (struct st_device *dev)
11192 {
11193   SANE_Byte data = 15;
11194 
11195   DBG (DBG_FNC, "+ Refs_Counter_Load:\n");
11196 
11197   /* check if chipset supports accessing eeprom */
11198   if ((dev->chipset->capabilities & CAP_EEPROM) != 0)
11199     if (RTS_EEPROM_ReadByte (dev->usb_handle, 0x78, &data) != OK)
11200       data = 15;
11201 
11202   DBG (DBG_FNC, "- Refs_Counter_Load: %i\n", _B0 (data));
11203 
11204   return data;
11205 }
11206 
11207 static SANE_Int
Refs_Counter_Save(struct st_device * dev,SANE_Byte data)11208 Refs_Counter_Save (struct st_device *dev, SANE_Byte data)
11209 {
11210   SANE_Int rst = OK;
11211 
11212   DBG (DBG_FNC, "+ Refs_Counter_Save(data=%i):\n", data);
11213 
11214   /* check if chipset supports accessing eeprom */
11215   if ((dev->chipset->capabilities & CAP_EEPROM) != 0)
11216     {
11217       if (data > 15)
11218 	data = 15;
11219 
11220       rst = RTS_EEPROM_WriteByte (dev->usb_handle, 0x78, data);
11221     }
11222 
11223   DBG (DBG_FNC, "- Refs_Counter_Save: %i\n", rst);
11224 
11225   return rst;
11226 }
11227 
11228 static SANE_Int
Refs_Counter_Inc(struct st_device * dev)11229 Refs_Counter_Inc (struct st_device *dev)
11230 {
11231   SANE_Byte data;
11232 
11233   DBG (DBG_FNC, "+ Refs_Counter_Inc:\n");
11234 
11235   data = Refs_Counter_Load (dev) + 1;
11236 
11237   if (data >= 15)
11238     data = 0;
11239 
11240   Refs_Counter_Save (dev, data);
11241 
11242   DBG (DBG_FNC, "- Refs_Counter_Inc() : Count=%i\n", data);
11243 
11244   return OK;
11245 }
11246 
11247 static SANE_Int
Load_StripCoords(SANE_Int scantype,SANE_Int * ypos,SANE_Int * xpos)11248 Load_StripCoords (SANE_Int scantype, SANE_Int * ypos, SANE_Int * xpos)
11249 {
11250   SANE_Int iType;
11251 
11252   switch (scantype)
11253     {
11254     case 3:
11255       iType = CALIBNEGATIVEFILM;
11256       break;
11257     case 2:
11258       iType = CALIBTRANSPARENT;
11259       break;
11260     default:
11261       iType = CALIBREFLECTIVE;
11262       break;
11263     }
11264 
11265   *xpos = get_value (iType, WSTRIPXPOS, 0, FITCALIBRATE);
11266   *ypos = get_value (iType, WSTRIPYPOS, 0, FITCALIBRATE);
11267 
11268   DBG (DBG_FNC, "> Load_StripCoords(scantype=%s): ypos=%i, xpos=%i\n",
11269        dbg_scantype (scantype), *ypos, *xpos);
11270 
11271   return OK;
11272 }
11273 
11274 static SANE_Int
Head_Relocate(struct st_device * dev,SANE_Int speed,SANE_Int direction,SANE_Int ypos)11275 Head_Relocate (struct st_device *dev, SANE_Int speed, SANE_Int direction,
11276 	       SANE_Int ypos)
11277 {
11278   SANE_Int rst;
11279   SANE_Byte *Regs;
11280 
11281   DBG (DBG_FNC, "+ Head_Relocate(speed=%i, direction=%i, ypos=%i):\n", speed,
11282        direction, ypos);
11283 
11284   rst = ERROR;
11285 
11286   Regs = (SANE_Byte *) malloc (RT_BUFFER_LEN * sizeof (SANE_Byte));
11287   if (Regs != NULL)
11288     {
11289       struct st_motormove mymotor;
11290       struct st_motorpos mtrpos;
11291 
11292       memset (&mymotor, 0, sizeof (struct st_motormove));
11293       memcpy (Regs, dev->init_regs, RT_BUFFER_LEN * sizeof (SANE_Byte));
11294 
11295       if (speed < dev->motormove_count)
11296 	memcpy (&mymotor, dev->motormove[speed],
11297 		sizeof (struct st_motormove));
11298 
11299       /*83fe */
11300       mtrpos.coord_y = ypos;
11301       mtrpos.options =
11302 	MTR_ENABLED | ((direction == MTR_BACKWARD) ? MTR_BACKWARD :
11303 		       MTR_FORWARD);
11304       mtrpos.v12e448 = 0;
11305       mtrpos.v12e44c = 1;
11306 
11307       Motor_Move (dev, Regs, &mymotor, &mtrpos);
11308 
11309       /* waits 15 seconds */
11310       RTS_WaitScanEnd (dev, 15000);
11311 
11312       free (Regs);
11313       rst = OK;
11314     }
11315 
11316   DBG (DBG_FNC, "- Head_Relocate: %i\n", rst);
11317 
11318   return rst;
11319 }
11320 
11321 static SANE_Int
Calib_CreateFixedBuffers()11322 Calib_CreateFixedBuffers ()
11323 {
11324   SANE_Byte channel;
11325   SANE_Int ret;
11326 
11327   DBG (DBG_FNC, "> Calib_CreateFixedBuffers()\n");
11328 
11329   ret = OK;
11330   channel = 0;
11331 
11332   while ((channel < 3) && (ret == OK))
11333     {
11334       /* First table */
11335       if (fixed_black_shading[channel] == NULL)
11336 	fixed_black_shading[channel] =
11337 	  (USHORT *) malloc (0x7f8 * sizeof (USHORT));
11338 
11339       if (fixed_black_shading[channel] != NULL)
11340 	memset (fixed_black_shading[channel], 0, 0x7f8 * sizeof (USHORT));
11341       else
11342 	ret = ERROR;
11343 
11344       /* Second table */
11345       if (fixed_white_shading[channel] == NULL)
11346 	fixed_white_shading[channel] =
11347 	  (USHORT *) malloc (0x7f8 * sizeof (USHORT));
11348 
11349       if (fixed_white_shading[channel] != NULL)
11350 	memset (fixed_white_shading[channel], 0, 0x7f8 * sizeof (USHORT));
11351       else
11352 	ret = ERROR;
11353 
11354       channel++;
11355     }
11356 
11357   return ret;
11358 }
11359 
11360 static SANE_Int
Calib_CreateBuffers(struct st_device * dev,struct st_calibration * buffer,SANE_Int my14b4)11361 Calib_CreateBuffers (struct st_device *dev, struct st_calibration *buffer,
11362 		     SANE_Int my14b4)
11363 {
11364   SANE_Int ebp, ret, channel;
11365 
11366   ret = ERROR;
11367   dev = dev;
11368 
11369   buffer->shadinglength = scan.coord.width;
11370   ebp = 0x14;
11371 
11372   if (my14b4 != 0)
11373     {
11374       /* 673d */
11375       if (Calib_CreateFixedBuffers () == OK)
11376 	{
11377 	  for (channel = 0; channel < 3; channel++)
11378 	    {
11379 	      buffer->white_shading[channel] = fixed_white_shading[channel];
11380 	      buffer->black_shading[channel] = fixed_black_shading[channel];
11381 	    }
11382 	  ret = OK;
11383 	}
11384     }
11385   else
11386     {
11387       /* 677f */
11388       SANE_Int pos;
11389       channel = 0;
11390       while ((channel < 3) && (ret == OK))
11391 	{
11392 	  buffer->black_shading[channel] =
11393 	    (USHORT *) malloc (ebp +
11394 			       (buffer->shadinglength * sizeof (USHORT)));
11395 	  buffer->white_shading[channel] =
11396 	    (USHORT *) malloc (ebp +
11397 			       (buffer->shadinglength * sizeof (USHORT)));
11398 	  if ((buffer->black_shading[channel] != NULL)
11399 	      && (buffer->white_shading[channel] != NULL))
11400 	    {
11401 	      for (pos = 0; pos < buffer->shadinglength; pos++)
11402 		{
11403 		  buffer->black_shading[channel][pos] = 0x00;
11404 		  buffer->white_shading[channel][pos] = 0x4000;
11405 		}
11406 	      ret = OK;
11407 	    }
11408 	  else
11409 	    Calib_FreeBuffers (buffer);
11410 
11411 	  channel++;
11412 	}
11413     }
11414 
11415   DBG (DBG_FNC, "> Calib_CreateBuffers: *buffer, my14b4=%i): %i\n", my14b4,
11416        ret);
11417 
11418   return ret;
11419 }
11420 
11421 static void
Calib_FreeBuffers(struct st_calibration * caltables)11422 Calib_FreeBuffers (struct st_calibration *caltables)
11423 {
11424   DBG (DBG_FNC, "> Calib_FreeBuffers(*caltables)\n");
11425 
11426   if (caltables != NULL)
11427     {
11428       SANE_Int channel;
11429 
11430       for (channel = 0; channel < 3; channel++)
11431 	{
11432 	  if (caltables->black_shading[channel] != NULL)
11433 	    {
11434 	      free (caltables->black_shading[channel]);
11435 	      caltables->black_shading[channel] = NULL;
11436 	    }
11437 
11438 	  if (caltables->white_shading[channel] != NULL)
11439 	    {
11440 	      free (caltables->white_shading[channel]);
11441 	      caltables->white_shading[channel] = NULL;
11442 	    }
11443 	}
11444     }
11445 }
11446 
11447 static SANE_Int
Calib_LoadConfig(struct st_device * dev,struct st_calibration_config * calibcfg,SANE_Int scantype,SANE_Int resolution,SANE_Int bitmode)11448 Calib_LoadConfig (struct st_device *dev,
11449 		  struct st_calibration_config *calibcfg, SANE_Int scantype,
11450 		  SANE_Int resolution, SANE_Int bitmode)
11451 {
11452   SANE_Int section, a;
11453   struct st_autoref refcfg;
11454 
11455   DBG (DBG_FNC,
11456        "> Calib_LoadConfig(*calibcfg, scantype=%s, resolution=%i, bitmode=%i)\n",
11457        dbg_scantype (scantype), resolution, bitmode);
11458 
11459   switch (scantype)
11460     {
11461     case ST_NEG:
11462       section = CALIBNEGATIVEFILM;
11463       break;
11464     case ST_TA:
11465       section = CALIBTRANSPARENT;
11466       break;
11467     default:
11468       section = CALIBREFLECTIVE;
11469       break;
11470     }
11471 
11472   calibcfg->WStripXPos = get_value (section, WSTRIPXPOS, 0, FITCALIBRATE);
11473   calibcfg->WStripYPos = get_value (section, WSTRIPYPOS, 0, FITCALIBRATE);
11474   calibcfg->BStripXPos = get_value (section, BSTRIPXPOS, 0, FITCALIBRATE);
11475   calibcfg->BStripYPos = get_value (section, WSTRIPYPOS, 0, FITCALIBRATE);
11476 
11477   /* get calibration wrefs */
11478   cfg_wrefs_get (dev->sensorcfg->type, bitmode, resolution, scantype,
11479 		 &calibcfg->WRef[CL_RED], &calibcfg->WRef[CL_GREEN],
11480 		 &calibcfg->WRef[CL_BLUE]);
11481 
11482   /* 4913 */
11483 
11484   for (a = CL_RED; a <= CL_BLUE; a++)
11485     {
11486       WRef[a] = _B0 (calibcfg->WRef[a]);
11487 
11488       calibcfg->BRef[a] = get_value (section, BREFR + a, 10, FITCALIBRATE);
11489       calibcfg->OffsetEven1[a] =
11490 	get_value (section, OFFSETEVEN1R + a, 256, FITCALIBRATE);
11491       calibcfg->OffsetEven2[a] =
11492 	get_value (section, OFFSETEVEN2R + a, 0, FITCALIBRATE);
11493       calibcfg->OffsetOdd1[a] =
11494 	get_value (section, OFFSETODD1R + a, 256, FITCALIBRATE);
11495       calibcfg->OffsetOdd2[a] =
11496 	get_value (section, OFFSETODD2R + a, 0, FITCALIBRATE);
11497     }
11498 
11499   calibcfg->RefBitDepth =
11500     _B0 (get_value (section, REFBITDEPTH, 8, FITCALIBRATE));
11501   calibcfg->CalibOffset10n =
11502     _B0 (get_value (section, CALIBOFFSET10N, 3, FITCALIBRATE));
11503   calibcfg->CalibOffset20n =
11504     _B0 (get_value (section, CALIBOFFSET20N, 0, FITCALIBRATE));
11505   calibcfg->OffsetHeight =
11506     get_value (section, OFFSETHEIGHT, 10, FITCALIBRATE);
11507 
11508   /* 4ae9 */
11509 
11510   /* get left coordinate and length to calibrate offset */
11511   cfg_offset_get (dev->sensorcfg->type, resolution, scantype,
11512 		  &calibcfg->OffsetPixelStart, &calibcfg->OffsetNPixel);
11513 
11514   /*4c49 */
11515   calibcfg->OffsetNSigma = get_value (section, OFFSETNSIGMA, 2, FITCALIBRATE);
11516   calibcfg->OffsetTargetMax =
11517     get_value (section, OFFSETTARGETMAX, 0x32, FITCALIBRATE) * 0.01;
11518   calibcfg->OffsetTargetMin =
11519     get_value (section, OFFSETTARGETMIN, 2, FITCALIBRATE) * 0.01;
11520   calibcfg->OffsetBoundaryRatio1 =
11521     get_value (section, OFFSETBOUNDARYRATIO1, 0x64, FITCALIBRATE) * 0.01;
11522   calibcfg->OffsetBoundaryRatio2 =
11523     get_value (section, OFFSETBOUNDARYRATIO2, 0x64, FITCALIBRATE) * 0.01;
11524 
11525   calibcfg->OffsetAvgRatio1 =
11526     get_value (section, OFFSETAVGRATIO1, 0x64, FITCALIBRATE) * 0.01;
11527   calibcfg->OffsetAvgRatio2 =
11528     get_value (section, OFFSETAVGRATIO2, 0x64, FITCALIBRATE) * 0.01;
11529   calibcfg->AdcOffQuickWay =
11530     get_value (section, ADCOFFQUICKWAY, 1, FITCALIBRATE);
11531   calibcfg->AdcOffPredictStart =
11532     get_value (section, ADCOFFPREDICTSTART, 0xc8, FITCALIBRATE);
11533   calibcfg->AdcOffPredictEnd =
11534     get_value (section, ADCOFFPREDICTEND, 0x1f4, FITCALIBRATE);
11535   calibcfg->AdcOffEvenOdd =
11536     get_value (section, ADCOFFEVENODD, 1, FITCALIBRATE);
11537   calibcfg->OffsetTuneStep1 =
11538     _B0 (get_value (section, OFFSETTUNESTEP1, 1, FITCALIBRATE));
11539   calibcfg->OffsetTuneStep2 =
11540     _B0 (get_value (section, OFFSETTUNESTEP2, 1, FITCALIBRATE));
11541   calibcfg->CalibGain10n = get_value (section, CALIBGAIN10N, 1, FITCALIBRATE);
11542   calibcfg->CalibGain20n = get_value (section, CALIBGAIN20N, 0, FITCALIBRATE);
11543   calibcfg->CalibPAGOn = get_value (section, CALIBPAGON, 0, FITCALIBRATE);
11544 
11545   for (a = CL_RED; a <= CL_BLUE; a++)
11546     {
11547       calibcfg->OffsetAvgTarget[a] =
11548 	_B0 (get_value (section, OFFSETAVGTARGETR + a, 0x0d, FITCALIBRATE));
11549       calibcfg->PAG[a] = get_value (section, PAGR + a, 3, FITCALIBRATE);
11550       calibcfg->Gain1[a] = get_value (section, GAIN1R + a, 4, FITCALIBRATE);
11551       calibcfg->Gain2[a] = get_value (section, GAIN2R + a, 4, FITCALIBRATE);
11552       calibcfg->WShadingPreDiff[a] =
11553 	get_value (section, WSHADINGPREDIFFR + a, -1, FITCALIBRATE);
11554       calibcfg->BShadingPreDiff[a] =
11555 	get_value (section, BSHADINGPREDIFFR + a, 2, FITCALIBRATE);
11556     }
11557 
11558   calibcfg->GainHeight = get_value (section, GAINHEIGHT, 0x1e, FITCALIBRATE);
11559   calibcfg->GainTargetFactor =
11560     get_value (section, GAINTARGETFACTOR, 0x5a, FITCALIBRATE) * 0.01;
11561   calibcfg->TotShading = get_value (section, TOTSHADING, 0, FITCALIBRATE);
11562 
11563   /* White shading */
11564   calibcfg->WShadingOn = get_value (section, WSHADINGON, 3, FITCALIBRATE);
11565   calibcfg->WShadingHeight =
11566     get_value (section, WSHADINGHEIGHT, 0x18, FITCALIBRATE);
11567 
11568   /* Black shading */
11569   calibcfg->BShadingOn = get_value (section, BSHADINGON, 2, FITCALIBRATE);
11570   calibcfg->BShadingHeight =
11571     get_value (section, BSHADINGHEIGHT, 0x1e, FITCALIBRATE);
11572 
11573   calibcfg->BShadingDefCutOff =
11574     get_value (section, BSHADINGDEFCUTOFF, 0, FITCALIBRATE);
11575 
11576   refcfg.extern_boundary = 0;
11577   cfg_autoref_get (&refcfg);
11578   calibcfg->ExternBoundary = refcfg.extern_boundary * 0.01;
11579 
11580   calibcfg->EffectivePixel =
11581     cfg_effectivepixel_get (dev->sensorcfg->type, resolution);
11582 
11583   return OK;
11584 }
11585 
11586 static SANE_Int
Calib_AdcGain(struct st_device * dev,struct st_calibration_config * calibcfg,SANE_Int arg2,SANE_Int gaincontrol)11587 Calib_AdcGain (struct st_device *dev, struct st_calibration_config *calibcfg,
11588 	       SANE_Int arg2, SANE_Int gaincontrol)
11589 {
11590   /*
11591      0606F8E0   04F60738  |Arg1 = 04F60738
11592      0606F8E4   0606F90C  |Arg2 = 0606F90C calibcfg
11593      0606F8E8   00000001  |Arg3 = 00000001 arg2
11594      0606F8EC   00000001  \Arg4 = 00000001 gaincontrol
11595    */
11596 
11597   SANE_Int rst = ERROR;
11598   SANE_Byte *myRegs;		/*f1c0 */
11599 
11600   DBG (DBG_FNC, "+ Calib_AdcGain(*calibcfg, arg2=%i, gaincontrol=%i)\n", arg2,
11601        gaincontrol);
11602 
11603   myRegs = (SANE_Byte *) malloc (sizeof (SANE_Byte) * RT_BUFFER_LEN);
11604   if (myRegs != NULL)
11605     {
11606       struct st_scanparams *scancfg;	/*f17c */
11607       SANE_Int bytes_per_line, bytes_to_next_colour, bytes_per_pixel;
11608 
11609       /* get register values to perform adc gain calibration */
11610       memcpy (myRegs, &calibdata->Regs, sizeof (SANE_Byte) * RT_BUFFER_LEN);
11611 
11612       scancfg =
11613 	(struct st_scanparams *) malloc (sizeof (struct st_scanparams));
11614       if (scancfg != NULL)
11615 	{
11616 	  SANE_Byte *image, *pgain, *pcalgain;
11617 
11618 	  /* get proper scan configuration */
11619 	  memcpy (scancfg, &calibdata->scancfg,
11620 		  sizeof (struct st_scanparams));
11621 
11622 	  /* set gain control type */
11623 	  Lamp_SetGainMode (dev, myRegs, scancfg->resolution_x, gaincontrol);
11624 
11625 	  /* 8-bit depth */
11626 	  scancfg->depth = 8;
11627 
11628 	  /* set coordinates */
11629 	  if ((scan.scantype > 0) && (scan.scantype < 4))
11630 	    scancfg->coord.left += scan.ser;
11631 
11632 	  if ((scancfg->coord.width & 1) == 0)
11633 	    scancfg->coord.width++;
11634 
11635 	  scancfg->coord.top = 1;
11636 	  scancfg->coord.height = calibcfg->OffsetHeight;
11637 
11638 	  /* three more values to read image data after getting image from scanner */
11639 	  switch (scancfg->colormode)
11640 	    {
11641 	    case CM_GRAY:
11642 	    case CM_LINEART:
11643 	      bytes_to_next_colour = 0;
11644 	      bytes_per_pixel = 1;
11645 	      bytes_per_line = scancfg->coord.width;
11646 	      break;
11647 	    default:		/* CM_COLOR */
11648 	      /* c027 */
11649 	      bytes_to_next_colour = 1;
11650 	      bytes_per_line = scancfg->coord.width * 3;
11651 	      if (scancfg->samplerate == LINE_RATE)
11652 		{
11653 		  bytes_to_next_colour = scancfg->coord.width;
11654 		  bytes_per_pixel = 1;
11655 		}
11656 	      else
11657 		bytes_per_pixel = 3;
11658 	      break;
11659 	    }
11660 
11661 	  /*7fc7 */
11662 	  scancfg->v157c = bytes_per_line;
11663 	  scancfg->bytesperline = bytes_per_line;
11664 
11665 	  /* select type of gain parameters to set */
11666 	  if (arg2 != 0)
11667 	    {
11668 	      pgain = calibdata->gain_offset.vgag1;
11669 	      pcalgain = calibcfg->Gain1;
11670 	    }
11671 	  else
11672 	    {
11673 	      /*7ff2 */
11674 	      pgain = calibdata->gain_offset.vgag2;
11675 	      pcalgain = calibcfg->Gain2;
11676 	    }
11677 
11678 	  /*8002 */
11679 	  /* Allocate space for image  | size = 132912 */
11680 	  image =
11681 	    (SANE_Byte *) malloc (sizeof (SANE_Byte) *
11682 				  ((scancfg->coord.height +
11683 				    16) * bytes_per_line));
11684 	  if (image != NULL)
11685 	    {
11686 	      /* Lets read image */
11687 	      if (RTS_GetImage
11688 		  (dev, myRegs, scancfg, &calibdata->gain_offset, image, NULL,
11689 		   OP_STATIC_HEAD, gaincontrol) == OK)
11690 		{
11691 		  SANE_Int a;
11692 		  SANE_Int vmin[3], vmax[3];
11693 		  double dval[3] = { 0.0 };	/*f1a8 f1b0 f1b8 */
11694 		  SANE_Byte *pimage = image;
11695 
11696 		  /* initialize values */
11697 		  for (a = CL_RED; a <= CL_BLUE; a++)
11698 		    {
11699 		      calibcfg->unk1[a] = 0;
11700 		      calibcfg->unk2[a] = 0xff;
11701 
11702 		      vmin[a] = 0xff;
11703 		      vmax[a] = 0;
11704 		    }
11705 
11706 		  /* process image data */
11707 		  if (scancfg->coord.width > 0)
11708 		    {
11709 		      /*8104 */
11710 		      SANE_Int pos, myheight /*f164 */ ;
11711 		      SANE_Int chn_sum[3];
11712 
11713 		      for (pos = scancfg->coord.width; pos > 0; pos--)
11714 			{
11715 			  chn_sum[CL_RED] = chn_sum[CL_GREEN] =
11716 			    chn_sum[CL_BLUE] = 0;
11717 
11718 			  if (scancfg->coord.height > 0)
11719 			    for (myheight = 0;
11720 				 myheight < scancfg->coord.height; myheight++)
11721 			      for (a = CL_RED; a <= CL_BLUE; a++)
11722 				chn_sum[a] +=
11723 				  *(pimage + (bytes_per_line * myheight) +
11724 				    (bytes_to_next_colour * a));
11725 
11726 			  /*816e */
11727 			  for (a = CL_RED; a <= CL_BLUE; a++)
11728 			    {
11729 			      vmin[a] =
11730 				min (vmin[a],
11731 				     chn_sum[a] / scancfg->coord.height);
11732 			      vmax[a] =
11733 				max (vmax[a],
11734 				     chn_sum[a] / scancfg->coord.height);
11735 
11736 			      calibcfg->unk1[a] =
11737 				max (calibcfg->unk1[a], vmax[a]);
11738 			      calibcfg->unk2[a] =
11739 				min (calibcfg->unk1[a], vmin[a]);
11740 
11741 			      dval[a] += vmax[a] & 0xffff;
11742 			    }
11743 
11744 			  pimage += bytes_per_pixel;
11745 			}
11746 		    }
11747 
11748 		  /*82b0 */
11749 		  dval[CL_RED] /= scancfg->coord.width;
11750 		  dval[CL_GREEN] /= scancfg->coord.width;
11751 		  dval[CL_BLUE] /= scancfg->coord.width;
11752 
11753 		  DBG (DBG_FNC, " -> adcgain (av/l): r=%f, g=%f, b=%f\n",
11754 		       dval[CL_RED], dval[CL_GREEN], dval[CL_BLUE]);
11755 		  DBG (DBG_FNC, " ->         (max ): R=%i, G=%i, B=%i\n",
11756 		       calibcfg->unk1[CL_RED], calibcfg->unk1[CL_GREEN],
11757 		       calibcfg->unk1[CL_BLUE]);
11758 		  DBG (DBG_FNC, " ->         (min ): r=%i, g=%i, b=%i\n",
11759 		       calibcfg->unk2[CL_RED], calibcfg->unk2[CL_GREEN],
11760 		       calibcfg->unk2[CL_BLUE]);
11761 
11762 		  if (scancfg->colormode == CM_COLOR)
11763 		    {
11764 		      /*8353 */
11765 		      double dvalue;
11766 		      SANE_Int ival;
11767 
11768 		      for (a = CL_RED; a <= CL_BLUE; a++)
11769 			{
11770 			  dvalue =
11771 			    ((((calibcfg->WRef[a] * (1 << scancfg->depth)) *
11772 			       calibcfg->GainTargetFactor) * 0.00390625) /
11773 			     dval[a]) * ((44 - pgain[a]) / 40);
11774 			  if (dvalue > 0.9090909090909091)
11775 			    {
11776 			      /*83d7 */
11777 			      dvalue = min (44 - (40 / dvalue), 31);
11778 			      ival = dvalue;
11779 			      pgain[a] = _B0 (ival);
11780 			      pcalgain[a] = _B0 (ival);
11781 			    }
11782 			  else
11783 			    {
11784 			      pgain[a] = 0;
11785 			      pcalgain[a] = 0;
11786 			    }
11787 			}
11788 		    }
11789 		  else
11790 		    {
11791 		      /*843c */
11792 		      /*falta codigo */
11793 		      double dvalue;
11794 		      SANE_Int ival;
11795 
11796 		      dvalue =
11797 			((44 -
11798 			  pgain[CL_RED]) / 40) * ((((1 << scancfg->depth) *
11799 						    calibcfg->WRef[scancfg->
11800 								   channel]) *
11801 						   0.9) * 0.00390625) /
11802 			17.08509389671362;
11803 
11804 		      for (a = CL_RED; a <= CL_BLUE; a++)
11805 			{
11806 			  if (dvalue > 0.9090909090909091)
11807 			    {
11808 			      dvalue = min (44 - (40 / dvalue), 31);
11809 			      ival = dvalue;
11810 			      pgain[a] = _B0 (ival);
11811 			      pcalgain[a] = _B0 (ival);
11812 			    }
11813 			  else
11814 			    {
11815 			      /*84e3 */
11816 			      pgain[a] = 0;
11817 			      pcalgain[a] = 0;
11818 			    }
11819 			}
11820 		    }
11821 
11822 		  /*84fa */
11823 		  /* Save buffer */
11824 		  if (RTS_Debug->SaveCalibFile != FALSE)
11825 		    {
11826 		      dbg_tiff_save ("adcgain.tiff",
11827 				     scancfg->coord.width,
11828 				     scancfg->coord.height,
11829 				     scancfg->depth,
11830 				     CM_COLOR,
11831 				     scancfg->resolution_x,
11832 				     scancfg->resolution_y,
11833 				     image,
11834 				     (scancfg->coord.height +
11835 				      16) * bytes_per_line);
11836 		    }
11837 
11838 		  /* check if peak values are above offset average target + 5 */
11839 		  for (a = CL_RED; a <= CL_BLUE; a++)
11840 		    if (calibcfg->unk1[a] >= calibcfg->OffsetAvgTarget[a] + 5)
11841 		      {
11842 			rst = OK;
11843 			break;
11844 		      }
11845 		}
11846 
11847 	      free (image);
11848 	    }
11849 
11850 	  free (scancfg);
11851 	}
11852 
11853       free (myRegs);
11854     }
11855 
11856   /* v14b8 = (rst == OK)? 0: 1; */
11857 
11858   /* show */
11859   dbg_calibtable (&calibdata->gain_offset);
11860 
11861   DBG (DBG_FNC, "- Calib_AdcGain: %i\n", rst);
11862 
11863   return rst;
11864 }
11865 
11866 static SANE_Int
GainOffset_Save(struct st_device * dev,SANE_Int * offset,SANE_Byte * gain)11867 GainOffset_Save (struct st_device *dev, SANE_Int * offset, SANE_Byte * gain)
11868 {
11869   SANE_Int rst = OK;
11870 
11871   DBG (DBG_FNC, "+ GainOffset_Save(*offset, *gain):\n");
11872 
11873   /* check if chipset supports accessing eeprom */
11874   if ((dev->chipset->capabilities & CAP_EEPROM) != 0)
11875     {
11876       if ((offset != NULL) && (gain != NULL))
11877 	{
11878 	  SANE_Int a, crc, value;
11879 
11880 	  crc = 0x5B;
11881 	  for (a = CL_RED; a <= CL_BLUE; a++)
11882 	    {
11883 	      value = (*gain << 9) | *offset;
11884 	      crc = _B0 (abs (crc - _B0 (value)));
11885 	      rst =
11886 		RTS_EEPROM_WriteWord (dev->usb_handle, 0x70 + (a * 2), value);
11887 	    }
11888 
11889 	  if (rst == OK)
11890 	    rst = RTS_EEPROM_WriteByte (dev->usb_handle, 0x76, crc);
11891 	}
11892       else
11893 	rst = ERROR;
11894     }
11895 
11896   DBG (DBG_FNC, "- GainOffset_Save: %i\n", rst);
11897 
11898   return rst;
11899 }
11900 
11901 static SANE_Int
Calib_PAGain(struct st_device * dev,struct st_calibration_config * calibcfg,SANE_Int gainmode)11902 Calib_PAGain (struct st_device *dev, struct st_calibration_config *calibcfg,
11903 	      SANE_Int gainmode)
11904 {
11905   SANE_Byte *Regs;
11906   struct st_scanparams *scancfg;
11907   SANE_Int channel_size;
11908   SANE_Int bytes_to_next_colour = 0;
11909   SANE_Int bytes_per_pixel = 0;
11910   SANE_Int length = 0;
11911   SANE_Byte *image;
11912   double rst;
11913   SANE_Int ret = ERROR;
11914 
11915   DBG (DBG_FNC, "+ Calib_PAGain(*calibcfg, gainmode=%i)\n", gainmode);
11916 
11917   Regs = (SANE_Byte *) malloc (RT_BUFFER_LEN * sizeof (SANE_Byte));
11918   if (Regs != NULL)
11919     {
11920       scancfg =
11921 	(struct st_scanparams *) malloc (sizeof (struct st_scanparams));
11922       if (scancfg != NULL)
11923 	{
11924 	  memcpy (Regs, &calibdata->Regs, RT_BUFFER_LEN * sizeof (SANE_Byte));
11925 	  memcpy (scancfg, &calibdata->scancfg,
11926 		  sizeof (struct st_scanparams));
11927 
11928 	  if (scan.scantype == ST_NORMAL)
11929 	    {
11930 	      /* bfa5 */
11931 	      scancfg->coord.left = scan.ser;
11932 	      scancfg->coord.width = (scancfg->sensorresolution * 17) / 2;
11933 	    }
11934 	  else
11935 	    {
11936 	      scancfg->coord.left = scan.ser + v0750;
11937 	      scancfg->coord.width = (scancfg->sensorresolution * 3) / 2;
11938 	    }
11939 
11940 	  /* bfca */
11941 	  if ((scancfg->coord.width & 1) == 1)
11942 	    scancfg->coord.width++;
11943 
11944 	  scancfg->coord.top = 1;
11945 	  scancfg->coord.height = calibcfg->OffsetHeight;
11946 
11947 	  channel_size = (scancfg->depth > 8) ? 2 : 1;
11948 
11949 	  switch (scancfg->colormode)
11950 	    {
11951 	    case CM_GRAY:
11952 	    case CM_LINEART:
11953 	      bytes_to_next_colour = 0;
11954 	      bytes_per_pixel = 1;
11955 	      length = channel_size * scancfg->coord.width;
11956 	      break;
11957 	    default:		/* CM_COLOR */
11958 	      /* c027 */
11959 	      bytes_to_next_colour = 1;
11960 	      length = (channel_size * scancfg->coord.width) * 3;
11961 	      if (scancfg->samplerate == LINE_RATE)
11962 		{
11963 		  bytes_to_next_colour = scancfg->coord.width;
11964 		  bytes_per_pixel = 1;
11965 		}
11966 	      else
11967 		bytes_per_pixel = 3;
11968 	      break;
11969 	    }
11970 
11971 	  /* c070 */
11972 	  scancfg->v157c = length;
11973 
11974 	  image =
11975 	    (SANE_Byte *) malloc ((scancfg->coord.height * length) *
11976 				  sizeof (SANE_Byte));
11977 	  if (image != NULL)
11978 	    {
11979 	      ret =
11980 		RTS_GetImage (dev, Regs, scancfg, &calibdata->gain_offset,
11981 			      image, 0, OP_STATIC_HEAD, gainmode);
11982 	      if (ret == OK)
11983 		{
11984 		  /* 429c105 */
11985 		  SANE_Int a;
11986 		  SANE_Byte *ptr[3];
11987 		  SANE_Int vmin[3] = { 255, 255, 255 };	/* f16c|f16e|f170 */
11988 		  SANE_Int vmax[3] = { 0, 0, 0 };	/* f164|f166|f168 */
11989 		  SANE_Int total[3];
11990 
11991 		  ptr[CL_RED] = image;
11992 		  ptr[CL_GREEN] = image + bytes_to_next_colour;
11993 		  ptr[CL_BLUE] = image + (bytes_to_next_colour * 2);
11994 
11995 		  if (scancfg->coord.width > 0)
11996 		    {
11997 		      SANE_Int pos, b;
11998 
11999 		      for (pos = 0; pos < scancfg->coord.width; pos++)
12000 			{
12001 			  total[CL_BLUE] = 0;
12002 			  total[CL_GREEN] = 0;
12003 			  total[CL_RED] = 0;
12004 
12005 			  for (a = 0; a < scancfg->coord.height; a++)
12006 			    {
12007 			      for (b = CL_RED; b <= CL_BLUE; b++)
12008 				total[b] +=
12009 				  *(ptr[b] +
12010 				    ((scancfg->coord.height - a) * length));
12011 			    }
12012 
12013 			  /* c1a5 */
12014 			  for (a = CL_RED; a <= CL_BLUE; a++)
12015 			    {
12016 			      total[a] /= scancfg->coord.height;
12017 			      vmin[a] = min (vmin[a], total[a]);
12018 			      vmax[a] = max (vmax[a], total[a]);
12019 
12020 			      ptr[a] += bytes_per_pixel;
12021 			    }
12022 			}
12023 		    }
12024 
12025 		  /* 429c234 */
12026 		  for (a = CL_RED; a <= CL_BLUE; a++)
12027 		    {
12028 		      rst =
12029 			(calibcfg->WRef[a] * calibcfg->GainTargetFactor) /
12030 			vmax[a];
12031 		      if (rst <= 1.5)
12032 			{
12033 			  if (rst <= 1.286)
12034 			    {
12035 			      if (rst <= 1.125)
12036 				calibdata->gain_offset.pag[a] = 0;
12037 			      else
12038 				calibdata->gain_offset.pag[a] = 1;
12039 			    }
12040 			  else
12041 			    calibdata->gain_offset.pag[a] = 2;
12042 			}
12043 		      else
12044 			calibdata->gain_offset.pag[a] = 3;
12045 		    }
12046 		}
12047 	      free (image);
12048 	    }
12049 	  free (scancfg);
12050 	}
12051       free (Regs);
12052     }
12053 
12054   DBG (DBG_FNC, "- Calib_PAGain: %i\n", ret);
12055 
12056   return ret;
12057 }
12058 
12059 static SANE_Int
Chipset_ID(struct st_device * dev)12060 Chipset_ID (struct st_device *dev)
12061 {
12062   SANE_Int ret;
12063 
12064   if (Read_Word (dev->usb_handle, 0xfe3c, &ret) == OK)
12065     ret = _B0 (ret);
12066   else
12067     ret = 0;
12068 
12069   DBG (DBG_FNC, "> Chipset_ID(): %i\n", ret);
12070 
12071   return ret;
12072 }
12073 
12074 static SANE_Int
Chipset_Name(struct st_device * dev,char * name,SANE_Int size)12075 Chipset_Name (struct st_device *dev, char *name, SANE_Int size)
12076 {
12077   SANE_Int rst = ERROR;
12078 
12079   if (name != NULL)
12080     {
12081       strncpy (name, dev->chipset->name, size);
12082       rst = OK;
12083     }
12084 
12085   return rst;
12086 }
12087 
12088 static SANE_Int
Refs_Load(struct st_device * dev,SANE_Int * x,SANE_Int * y)12089 Refs_Load (struct st_device *dev, SANE_Int * x, SANE_Int * y)
12090 {
12091   SANE_Int ret = OK;
12092 
12093   DBG (DBG_FNC, "+ Refs_Load:\n");
12094 
12095   *y = *x = 0;
12096 
12097   /* check if chipset supports accessing eeprom */
12098   if ((dev->chipset->capabilities & CAP_EEPROM) != 0)
12099     {
12100       SANE_Int data;
12101 
12102       ret = ERROR;
12103 
12104       if (RTS_EEPROM_ReadWord (dev->usb_handle, 0x6a, &data) == OK)
12105 	{
12106 	  *x = data;
12107 	  if (RTS_EEPROM_ReadWord (dev->usb_handle, 0x6c, &data) == OK)
12108 	    {
12109 	      *y = data;
12110 	      if (RTS_EEPROM_ReadWord (dev->usb_handle, 0x6e, &data) == OK)
12111 		{
12112 		  if ((_B0 (*y + *x + data)) == 0x5a)
12113 		    ret = OK;
12114 		}
12115 	    }
12116 	}
12117     }
12118 
12119   DBG (DBG_FNC, "- Refs_Load(y=%i, x=%i) : %i\n", *y, *x, ret);
12120 
12121   return ret;
12122 }
12123 
12124 static SANE_Int
Refs_Save(struct st_device * dev,SANE_Int left_leading,SANE_Int start_pos)12125 Refs_Save (struct st_device *dev, SANE_Int left_leading, SANE_Int start_pos)
12126 {
12127   SANE_Int ret = OK;
12128 
12129   DBG (DBG_FNC, "+ Refs_Save(left_leading=%i, start_pos=%i)\n", left_leading,
12130        start_pos);
12131 
12132   /* check if chipset supports accessing eeprom */
12133   if ((dev->chipset->capabilities & CAP_EEPROM) != 0)
12134     {
12135       ret = ERROR;
12136 
12137       if (RTS_EEPROM_WriteWord (dev->usb_handle, 0x6a, left_leading) == OK)
12138 	{
12139 	  if (RTS_EEPROM_WriteWord (dev->usb_handle, 0x6c, start_pos) == OK)
12140 	    {
12141 	      SANE_Byte data = _B0 (0x5a - (start_pos + left_leading));
12142 	      ret = RTS_EEPROM_WriteByte (dev->usb_handle, 0x6e, data);
12143 	    }
12144 	}
12145     }
12146 
12147   DBG (DBG_FNC, "- Refs_Save: %i\n", ret);
12148 
12149   return ret;
12150 }
12151 
12152 static SANE_Int
Calib_AdcOffsetRT(struct st_device * dev,struct st_calibration_config * calibcfg,SANE_Int value)12153 Calib_AdcOffsetRT (struct st_device *dev,
12154 		   struct st_calibration_config *calibcfg, SANE_Int value)
12155 {
12156 /*
12157 05EFF8E4   04F10738  |Arg1 = 04F10738
12158 05EFF8E8   05EFF90C  |Arg2 = 05EFF90C calibcfg
12159 05EFF8EC   00000001  \Arg3 = 00000001 value
12160 */
12161   SANE_Byte Regs[RT_BUFFER_LEN];	/*f1c4 */
12162   SANE_Int channels_per_dot;	/*f108 */
12163   struct st_scanparams scancfg;	/*f18c */
12164   SANE_Int *pedcg;		/*f114 */
12165   SANE_Int *podcg;		/*f118 */
12166   SANE_Int *poffseteven;	/*f130 */
12167   SANE_Int *poffsetodd;		/*f128 */
12168   SANE_Int channel;
12169   SANE_Int avgtarget[3];	/*f1b8 f1bc f1c0 */
12170   SANE_Byte *scanbuffer;	/*f0f8 */
12171   SANE_Int scan_options;	/*f12c */
12172   SANE_Int highresolution;	/*f144 */
12173   double dbValues[3] = { 0, 0, 0 };	/*f148 f14c f150 */
12174   SANE_Int do_loop;		/*f0ec */
12175   SANE_Int gainmode;
12176   SANE_Byte *ptr;		/*f0f4 */
12177   SANE_Byte *mvgag;		/*f0e4 *//*f10c */
12178   USHORT wvalues[9];		/*0856 0858 085a 085c 085e 0860 0862 0864 0866 */
12179   SANE_Int imgcount = 0;
12180   /* myoffsetnpixel = f120 */
12181   /* desp f0e8 & f140 */
12182 
12183   DBG (DBG_FNC, "+ Calib_AdcOffsetRT(*calibcfg, value=%i)\n", value);
12184 
12185   memcpy (&Regs, &calibdata->Regs, RT_BUFFER_LEN * sizeof (SANE_Byte));
12186   memcpy (&scancfg, &calibdata->scancfg, sizeof (struct st_scanparams));
12187 
12188   channels_per_dot = (calibdata->scancfg.colormode == CM_COLOR) ? 3 : 1;
12189 
12190   if (value != 0)
12191     {
12192       pedcg = &calibdata->gain_offset.edcg1[CL_RED];
12193       podcg = &calibdata->gain_offset.odcg1[CL_RED];
12194       poffseteven = &calibcfg->OffsetEven1[CL_RED];
12195       poffsetodd = &calibcfg->OffsetOdd1[CL_RED];
12196     }
12197   else
12198     {
12199       /*c37c */
12200       pedcg = &calibdata->gain_offset.edcg2[CL_RED];
12201       podcg = &calibdata->gain_offset.odcg2[CL_RED];
12202       poffseteven = &calibcfg->OffsetEven2[CL_RED];
12203       poffsetodd = &calibcfg->OffsetOdd2[CL_RED];
12204     }
12205 
12206   /*c3a4 */
12207   scancfg.coord.left = calibcfg->OffsetPixelStart;
12208 
12209   if (channels_per_dot > 0)
12210     {
12211       for (channel = 0; channel < channels_per_dot; channel++)
12212 	{
12213 	  avgtarget[channel] = calibcfg->OffsetAvgTarget[channel] << 8;
12214 	  if (avgtarget[channel] == 0)
12215 	    avgtarget[channel] = 0x80;
12216 	}
12217     }
12218 
12219   /* set image coordinates to scan */
12220   scancfg.coord.width = calibcfg->OffsetNPixel;
12221   if ((scancfg.coord.width & 1) == 0)
12222     scancfg.coord.width++;
12223 
12224   scancfg.bytesperline = channels_per_dot * scancfg.coord.width;
12225   scancfg.coord.top = 1;
12226   scancfg.coord.height = calibcfg->OffsetHeight;
12227   scancfg.depth = 8;
12228 
12229   /* allocate memory to store image */
12230   scanbuffer =
12231     (SANE_Byte *) malloc ((scancfg.bytesperline * calibcfg->OffsetHeight) *
12232 			  sizeof (SANE_Byte));
12233   if (scanbuffer == NULL)
12234     return ERROR;
12235 
12236   /*42ac477 */
12237   scan_options = (linedarlampoff == 1) ? 1 : 0x101;
12238   highresolution = (scancfg.sensorresolution >= 1200) ? TRUE : FALSE;
12239 
12240   do
12241     {
12242       if (channels_per_dot > 0)
12243 	{
12244 	  for (channel = 0; channel < channels_per_dot; channel++)
12245 	    dbValues[channel] =
12246 	      (40 / (44 - calibdata->gain_offset.vgag2[channel])) * (40 /
12247 								     (44 -
12248 								      calibdata->
12249 								      gain_offset.
12250 								      vgag1
12251 								      [channel]));
12252 	}
12253 
12254       /*429c50f */
12255       /* Get Image */
12256       gainmode = Lamp_GetGainMode (dev, scancfg.resolution_x, scan.scantype);
12257       if (RTS_GetImage
12258 	  (dev, Regs, &scancfg, &calibdata->gain_offset, scanbuffer, 0,
12259 	   scan_options, gainmode) != OK)
12260 	{
12261 	  free (scanbuffer);
12262 	  return ERROR;
12263 	}
12264 
12265       /*429c55f */
12266       /* Save retrieved image */
12267       if (RTS_Debug->SaveCalibFile != FALSE)
12268 	{
12269 	  char fname[30];
12270 
12271 	  imgcount++;
12272 	  if (snprintf (fname, 30, "adcoffset_rt%i.tiff", imgcount) > 0)
12273 	    dbg_tiff_save (fname,
12274 			   scancfg.coord.width,
12275 			   scancfg.coord.height,
12276 			   scancfg.depth,
12277 			   CM_COLOR,
12278 			   scancfg.resolution_x,
12279 			   scancfg.resolution_y,
12280 			   scanbuffer,
12281 			   scancfg.bytesperline * calibcfg->OffsetHeight);
12282 	}
12283 
12284       /*429c5a5 */
12285       do_loop = FALSE;
12286 
12287       if (highresolution == TRUE)
12288 	{
12289 	  /* f0fc = f0e4 = channel */
12290 	  SANE_Int lf104;
12291 	  SANE_Int *mydcg;	/*f0f4 */
12292 	  USHORT *mywvalue;	/*ebp */
12293 
12294 	  SANE_Byte is_ready[6];	/*f174 f178 f17c f180 f184 f18c */
12295 	  SANE_Byte *ptr_ready;	/*f11c */
12296 	  SANE_Int colour;
12297 
12298 	  for (channel = 0; channel < 6; channel++)
12299 	    is_ready[channel] = FALSE;
12300 
12301 	  if (channels_per_dot <= 0)
12302 	    break;
12303 
12304 	  ptr = scanbuffer;
12305 	  mvgag = (SANE_Byte *) calibdata->gain_offset.vgag1;
12306 
12307 	  for (channel = 0; channel < channels_per_dot; channel++)
12308 	    {
12309 	      for (lf104 = 0; lf104 < 2; lf104++)
12310 		{
12311 		  if (lf104 == 0)
12312 		    {
12313 		      mywvalue = &wvalues[channel];
12314 		      mydcg = pedcg;
12315 		      ptr_ready = &is_ready[0];
12316 		    }
12317 		  else
12318 		    {
12319 		      /*1645 */
12320 		      mywvalue = &wvalues[3];
12321 		      mydcg = podcg;
12322 		      ptr_ready = &is_ready[3];
12323 		    }
12324 
12325 		  /*1658 */
12326 		  if (ptr_ready[channel] == FALSE)
12327 		    {
12328 		      colour = 0;
12329 		      if (lf104 < calibcfg->OffsetNPixel)
12330 			{
12331 			  SANE_Int dot;
12332 
12333 			  for (dot = 0;
12334 			       dot < (calibcfg->OffsetNPixel - lf104 + 1) / 2;
12335 			       dot++)
12336 			    colour +=
12337 			      scanbuffer[mvgag[(lf104 * channels_per_dot)] +
12338 					 (dot * (channels_per_dot * 2))];
12339 			}
12340 
12341 		      /*c6b2 */
12342 		      colour = colour << 8;
12343 		      if (colour == 0)
12344 			{
12345 			  /*c6b9 */
12346 			  if (mydcg[channel] != 0x1ff)
12347 			    {
12348 			      /*c6d5 */
12349 			      mydcg[channel] = 0x1ff;
12350 			      do_loop = TRUE;
12351 			    }
12352 			  else
12353 			    ptr_ready[channel] = TRUE;
12354 			}
12355 		      else
12356 			{
12357 			  SANE_Int myesi;
12358 			  SANE_Int d;
12359 
12360 			  /*c6e8 */
12361 			  if (*mywvalue == 0)
12362 			    mywvalue += 2;
12363 
12364 			  colour /= (calibcfg->OffsetNPixel / 2);
12365 			  if (colour >= avgtarget[channel])
12366 			    {
12367 			      colour -= avgtarget[channel];
12368 			      myesi = 0;
12369 			    }
12370 			  else
12371 			    {
12372 			      colour = avgtarget[channel] - colour;
12373 			      myesi = 1;
12374 			    }
12375 
12376 			  d = mydcg[channel];
12377 			  if (d < 0x100)
12378 			    d = 0xff - d;
12379 
12380 			  if (myesi != 0)
12381 			    {
12382 			      /*c76e */
12383 			      if ((d + colour) > 0x1ff)
12384 				{
12385 				  if (*mvgag > 0)
12386 				    {
12387 				      *mvgag = *mvgag - 1;
12388 				      do_loop = TRUE;
12389 				    }
12390 				  else
12391 				    ptr_ready[channel] = TRUE;	/*c7a0 */
12392 				}
12393 			      else
12394 				d += colour;
12395 			    }
12396 			  else
12397 			    {
12398 			      /*c7ad */
12399 			      if (colour > d)
12400 				{
12401 				  if (*mvgag > 0)
12402 				    {
12403 				      *mvgag = *mvgag - 1;
12404 				      do_loop = TRUE;
12405 				    }
12406 				  else
12407 				    ptr_ready[channel] = TRUE;
12408 				}
12409 			      else
12410 				d -= colour;
12411 			    }
12412 
12413 			  /*c7dd */
12414 			  mydcg[channel] = (d < 0x100) ? 0x100 - d : d;
12415 			}
12416 
12417 		      dbg_calibtable (&calibdata->gain_offset);
12418 		    }
12419 		}
12420 
12421 	      /*c804 */
12422 	      mvgag++;
12423 	    }
12424 	}
12425       else
12426 	{
12427 	  /* Low resolution */
12428 
12429 	  SANE_Byte is_ready[3];
12430 	  SANE_Int colour;
12431 
12432 	  /*429c845 */
12433 	  for (channel = 0; channel < channels_per_dot; channel++)
12434 	    is_ready[channel] = FALSE;
12435 
12436 	  if (channels_per_dot <= 0)
12437 	    break;
12438 
12439 	  ptr = scanbuffer;
12440 	  mvgag = (SANE_Byte *) calibdata->gain_offset.vgag1;
12441 
12442 	  for (channel = 0; channel < channels_per_dot; channel++)
12443 	    {
12444 	      if (is_ready[channel] == FALSE)
12445 		{
12446 		  colour = 0;
12447 		  if (calibcfg->OffsetNPixel > 0)
12448 		    {
12449 		      SANE_Int dot;
12450 
12451 		      /* Take one channel colour values from offsetnpixel pixels */
12452 		      for (dot = 0; dot < calibcfg->OffsetNPixel; dot++)
12453 			colour += *(ptr + (dot * channels_per_dot));
12454 		    }
12455 
12456 		  colour <<= 8;
12457 		  if (colour == 0)
12458 		    {
12459 		      if (pedcg[channel] != 0x1ff)
12460 			{
12461 			  do_loop = TRUE;
12462 			  podcg[channel] = 0x1ff;
12463 			  pedcg[channel] = 0x1ff;
12464 			}
12465 		      else
12466 			is_ready[channel] = TRUE;
12467 		    }
12468 		  else
12469 		    {
12470 		      /*c8f7 */
12471 		      SANE_Int myesi;
12472 		      SANE_Int op1, op2, op3;
12473 
12474 		      /* Get colour average */
12475 		      colour /= calibcfg->OffsetNPixel;
12476 
12477 		      /* get absolute difference with avgtarget */
12478 		      myesi = (colour > avgtarget[channel]) ? 0 : 1;
12479 		      colour = abs (avgtarget[channel] - colour);
12480 
12481 		      if (scancfg.resolution_x > 600)
12482 			{
12483 			  /*c923 */
12484 			  if (wvalues[channel + 3] == 0)
12485 			    wvalues[channel + 3]++;
12486 
12487 			  if (wvalues[channel] == 0)
12488 			    wvalues[channel]++;
12489 
12490 			  op3 = max (wvalues[channel], wvalues[channel + 3]);
12491 			}
12492 		      else
12493 			{
12494 			  if (wvalues[channel + 6] == 0)
12495 			    wvalues[channel + 6]++;
12496 
12497 			  op3 = wvalues[channel + 6];
12498 			}
12499 
12500 		      /*c9d3 */
12501 		      op1 = (SANE_Int) (colour / (dbValues[channel] * op3));
12502 		      op2 =
12503 			(pedcg[channel] <
12504 			 0x100) ? pedcg[channel] - 0xff : pedcg[channel];
12505 
12506 		      if (myesi != 0)
12507 			{
12508 			  /*c9f5 */
12509 			  if (((op2 + op1) & 0xffff) > 0x1ff)
12510 			    {
12511 			      if (*mvgag != 0)
12512 				{
12513 				  do_loop = TRUE;
12514 				  *mvgag = *mvgag - 1;
12515 				}
12516 			      else
12517 				is_ready[channel] = TRUE;
12518 			    }
12519 			  else
12520 			    op2 += op1;
12521 			}
12522 		      else
12523 			{
12524 			  /*ca31 */
12525 			  if (op1 > op2)
12526 			    {
12527 			      if (*mvgag > 0)
12528 				{
12529 				  do_loop = TRUE;
12530 				  *mvgag = *mvgag - 1;
12531 				}
12532 			      else
12533 				is_ready[channel] = TRUE;
12534 			    }
12535 			  else
12536 			    op2 -= op1;
12537 			}
12538 
12539 		      /*ca54 */
12540 		      if (op2 < 0x100)
12541 			op2 = 0x100 - op2;
12542 
12543 		      pedcg[channel] = op2;
12544 		      podcg[channel] = op2;
12545 		    }
12546 		}
12547 	      /*ca6f */
12548 	      ptr++;
12549 	      mvgag++;
12550 	      dbg_calibtable (&calibdata->gain_offset);
12551 	    }
12552 	}
12553     }
12554   while (do_loop != FALSE);
12555 
12556   /*429cad1 */
12557   for (channel = 0; channel < 3; channel++)
12558     {
12559       poffseteven[channel] =
12560 	(pedcg[channel] < 0x100) ? 0xff - pedcg[channel] : pedcg[channel];
12561       poffsetodd[channel] =
12562 	(podcg[channel] < 0x100) ? 0xff - podcg[channel] : podcg[channel];
12563     }
12564 
12565   free (scanbuffer);
12566 
12567   return OK;
12568 }
12569 
12570 static void
Calib_LoadCut(struct st_device * dev,struct st_scanparams * scancfg,SANE_Int scantype,struct st_calibration_config * calibcfg)12571 Calib_LoadCut (struct st_device *dev, struct st_scanparams *scancfg,
12572 	       SANE_Int scantype, struct st_calibration_config *calibcfg)
12573 {
12574   double mylong;		/*ee78 */
12575   double mylong2;
12576   /**/ SANE_Int channel[3];
12577   SANE_Int a;
12578 
12579   cfg_shading_cut_get (dev->sensorcfg->type, scancfg->depth,
12580 		       scancfg->resolution_x, scantype, &channel[0],
12581 		       &channel[1], &channel[2]);
12582 
12583   mylong = 1 << scancfg->depth;
12584 
12585   for (a = CL_RED; a <= CL_BLUE; a++)
12586     {
12587       mylong2 = channel[a];
12588       calibcfg->ShadingCut[a] = (mylong * mylong2) * 0.000390625;
12589     }
12590 }
12591 
12592 static SANE_Int
Calib_BWShading(struct st_calibration_config * calibcfg,struct st_calibration * myCalib,SANE_Int gainmode)12593 Calib_BWShading (struct st_calibration_config *calibcfg,
12594 		 struct st_calibration *myCalib, SANE_Int gainmode)
12595 {
12596   /*
12597      0603F8E4   0603F90C  |Arg1 = 0603F90C calibcfg
12598      0603F8E8   0603FAAC  |Arg2 = 0603FAAC myCalib
12599      0603F8EC   00000001  \Arg3 = 00000001 gainmode
12600    */
12601 
12602   /*falta codigo */
12603 
12604   /*silence gcc */
12605   calibcfg = calibcfg;
12606   myCalib = myCalib;
12607   gainmode = gainmode;
12608 
12609   return OK;
12610 }
12611 
12612 static SANE_Int
Calib_WhiteShading_3(struct st_device * dev,struct st_calibration_config * calibcfg,struct st_calibration * myCalib,SANE_Int gainmode)12613 Calib_WhiteShading_3 (struct st_device *dev,
12614 		      struct st_calibration_config *calibcfg,
12615 		      struct st_calibration *myCalib, SANE_Int gainmode)
12616 {
12617 /*
12618 05EDF8E0   04F00738  |Arg1 = 04F00738
12619 05EDF8E4   05EDF90C  |Arg2 = 05EDF90C calibcfg
12620 05EDF8E8   05EDFAAC  |Arg3 = 05EDFAAC myCalib
12621 05EDF8EC   00000001  \Arg4 = 00000001 gainmode
12622 */
12623   SANE_Byte *myRegs;		/*f1bc */
12624   struct st_scanparams scancfg;	/*f170 */
12625   SANE_Int myWidth;		/*f14c */
12626   SANE_Int lf168, bytes_per_pixel;
12627   SANE_Int bytes_per_line;
12628   /**/ SANE_Int a;
12629   double lf1a4[3];
12630   SANE_Int otherheight;		/*f150 */
12631   SANE_Int otherheight2;
12632   SANE_Int lf12c;
12633   SANE_Int lf130;
12634   double *buffer1;		/*f138 */
12635   double *buffer2;		/*f144 */
12636   SANE_Byte *scanbuffer;	/*f164 */
12637   SANE_Byte *ptr;		/*f148 */
12638   SANE_Int position;		/*f140 */
12639   SANE_Int lf13c, myHeight;
12640   SANE_Int myESI, myEDI;
12641   SANE_Int channel;		/*f134 */
12642   double myst;
12643   double sumatorio;
12644   SANE_Int rst;
12645 
12646   DBG (DBG_FNC, "> Calib_WhiteShading3(*calibcfg, *myCalib, gainmode=%i)\n",
12647        gainmode);
12648 
12649   myRegs = (SANE_Byte *) malloc (RT_BUFFER_LEN * sizeof (SANE_Byte));
12650   memcpy (myRegs, &calibdata->Regs, RT_BUFFER_LEN * sizeof (SANE_Byte));
12651   memcpy (&scancfg, &calibdata->scancfg, sizeof (struct st_scanparams));
12652 
12653   Lamp_SetGainMode (dev, myRegs, scancfg.resolution_x, gainmode);
12654 
12655   rst = OK;
12656   scancfg.resolution_y = 200;
12657   switch (scan.scantype)
12658     {
12659     case ST_NORMAL:
12660       /*a184 */
12661       scancfg.coord.left += scan.ser;
12662       scancfg.coord.width &= 0xffff;
12663       break;
12664     case ST_TA:
12665     case ST_NEG:
12666       scancfg.coord.left += scan.ser;
12667       break;
12668     }
12669 
12670   /*a11b */
12671   if ((scancfg.coord.width & 1) != 0)
12672     scancfg.coord.width++;
12673 
12674   scancfg.coord.top = 1;
12675   scancfg.coord.height = calibcfg->WShadingHeight;
12676 
12677   switch (scancfg.colormode)
12678     {
12679     case CM_GRAY:
12680     case CM_LINEART:
12681       myWidth = scancfg.coord.width;
12682       lf168 = 0;
12683       bytes_per_line = ((scancfg.depth + 7) / 8) * myWidth;
12684       bytes_per_pixel = 1;
12685       break;
12686     default:			/* CM_COLOR */
12687       myWidth = scancfg.coord.width * 3;
12688       bytes_per_line = ((scancfg.depth + 7) / 8) * myWidth;
12689       lf168 = (scancfg.samplerate == LINE_RATE) ? scancfg.coord.width : 1;
12690       bytes_per_pixel = (scancfg.samplerate == PIXEL_RATE) ? 3 : 1;
12691       break;
12692     }
12693 
12694   /*a1e8 */
12695   scancfg.v157c = bytes_per_line;
12696   scancfg.bytesperline = bytes_per_line;
12697 
12698   for (a = 0; a < 3; a++)
12699     lf1a4[a] = (calibcfg->WRef[a] * (1 << scancfg.depth)) >> 8;
12700 
12701   /* debug this code because if it's correct, lf130 and lf12c are always 2 */
12702   otherheight = calibcfg->WShadingHeight - 3;
12703   otherheight -= (otherheight - 4);
12704   otherheight2 = otherheight / 2;
12705   otherheight -= otherheight2;
12706   lf130 = otherheight2;
12707   lf12c = otherheight;
12708 
12709   buffer1 = (double *) malloc (otherheight * sizeof (double));
12710   if (buffer1 == NULL)
12711     return ERROR;
12712 
12713   buffer2 = (double *) malloc (otherheight * sizeof (double));
12714   if (buffer2 == NULL)
12715     {
12716       free (buffer1);
12717       return ERROR;
12718     }
12719 
12720   scanbuffer =
12721     (SANE_Byte *) malloc (((scancfg.coord.height + 16) * bytes_per_line) *
12722 			  sizeof (SANE_Byte));
12723   if (scanbuffer == NULL)
12724     {
12725       free (buffer1);
12726       free (buffer2);
12727       return ERROR;
12728     }
12729 
12730   /* Scan image */
12731   myCalib->shading_enabled = FALSE;
12732   rst =
12733     RTS_GetImage (dev, myRegs, &scancfg, &calibdata->gain_offset, scanbuffer,
12734 		  myCalib, 0x20000080, gainmode);
12735 
12736   for (a = 0; a < 3; a++)
12737     myCalib->WRef[a] *= ((1 << scancfg.depth) >> 8);
12738 
12739   if (rst == ERROR)
12740     {
12741       free (buffer1);
12742       free (buffer2);
12743       free (scanbuffer);
12744       return ERROR;
12745     }
12746 
12747   if (scancfg.depth > 8)
12748     {
12749       /*a6d9 */
12750       position = 0;
12751       sumatorio = 0;
12752       if (myWidth > 0)
12753 	{
12754 	  do
12755 	    {
12756 	      switch (scancfg.colormode)
12757 		{
12758 		case CM_GRAY:
12759 		case CM_LINEART:
12760 		  channel = 0;
12761 		  lf13c = position;
12762 		  break;
12763 		default:	/*CM_COLOR */
12764 		  if (scancfg.samplerate == PIXEL_RATE)
12765 		    {
12766 		      /* pixel rate */
12767 		      channel = position % bytes_per_pixel;
12768 		      lf13c = position / bytes_per_pixel;
12769 		    }
12770 		  else
12771 		    {
12772 		      /* line rate */
12773 		      channel = position / lf168;
12774 		      lf13c = position % lf168;
12775 		    }
12776 		  break;
12777 		}
12778 
12779 	      /*a743 */
12780 	      if (lf130 > 0)
12781 		memset (buffer1, 0, lf130 * sizeof (double));
12782 
12783 	      /*a761 */
12784 	      if (lf12c > 0)
12785 		{
12786 		  for (a = 0; a < lf12c; a++)
12787 		    buffer2[a] = (1 << scancfg.depth) - 1.0;
12788 		}
12789 
12790 	      /*a78f */
12791 	      myESI = 0;
12792 	      myEDI = 0;
12793 	      ptr = scanbuffer + (position * 2);
12794 	      myHeight = 0;
12795 
12796 	      if (otherheight > 0)
12797 		{
12798 		  do
12799 		    {
12800 		      myst = 0;
12801 		      for (a = 0; a < 4; a++)
12802 			myst += data_lsb_get (ptr + (a * (myWidth * 2)), 2);
12803 
12804 		      myEDI = 0;
12805 		      myst = myst * 0.25;
12806 		      if (myHeight < (otherheight - 4))
12807 			{
12808 			  if (myst < buffer2[myESI])
12809 			    {
12810 			      buffer2[myESI] = myst;
12811 			      if (lf12c > 0)
12812 				{
12813 				  for (a = 0; a < lf12c; a++)
12814 				    if (buffer2[myESI] < buffer2[a])
12815 				      myESI = a;
12816 				}
12817 			    }
12818 
12819 			  /*a820 */
12820 			  if (myst >= buffer1[myEDI])
12821 			    {
12822 			      buffer1[myEDI] = myst;
12823 			      if (lf130 > 0)
12824 				{
12825 				  for (a = 0; a < lf130; a++)
12826 				    if (buffer1[myEDI] >= buffer1[a])
12827 				      myEDI = a;
12828 				}
12829 			    }
12830 			  sumatorio += myst;
12831 			}
12832 		      else
12833 			{
12834 			  /*a853 */
12835 			  if (myHeight == (otherheight - 4))
12836 			    {
12837 			      if (lf12c > 0)
12838 				{
12839 				  for (a = 0; a < lf12c; a++)
12840 				    if (buffer2[myESI] >= buffer2[a])
12841 				      myESI = a;
12842 				}
12843 
12844 			      if (lf130 > 0)
12845 				{
12846 				  for (a = 0; a < lf130; a++)
12847 				    if (buffer1[myEDI] < buffer1[a])
12848 				      myEDI = a;
12849 				}
12850 			    }
12851 
12852 			  /*a895 */
12853 			  if (myst >= buffer2[myESI])
12854 			    {
12855 			      /*a89c */
12856 			      sumatorio -= buffer2[myESI];
12857 			      sumatorio += myst;
12858 			      buffer2[myESI] = myst;
12859 			      if (lf12c > 0)
12860 				{
12861 				  for (a = 0; a < lf12c; a++)
12862 				    if (buffer2[myESI] >= buffer2[a])
12863 				      myESI = a;
12864 				}
12865 			    }
12866 			  else
12867 			    {
12868 			      if (myst < buffer1[myEDI])
12869 				{
12870 				  sumatorio -= buffer1[myEDI];
12871 				  sumatorio += myst;
12872 				  buffer1[myEDI] = myst;
12873 
12874 				  if (lf130 > 0)
12875 				    {
12876 				      for (a = 0; a < lf130; a++)
12877 					if (buffer1[myEDI] < buffer1[a])
12878 					  myEDI = a;
12879 				    }
12880 				}
12881 			    }
12882 			}
12883 
12884 		      /*a901 */
12885 		      ptr += (myWidth * 2);
12886 		      myHeight++;
12887 		    }
12888 		  while (myHeight < otherheight);
12889 		}
12890 
12891 	      /*a924 */
12892 	      scancfg.ser = 0;
12893 	      scancfg.startpos = otherheight - 4;
12894 
12895 	      sumatorio = sumatorio / scancfg.startpos;
12896 	      if (myCalib->shading_enabled != FALSE)
12897 		{
12898 		  /*a94a */
12899 		  myCalib->white_shading[channel][lf13c] =
12900 		    (unsigned short) sumatorio;
12901 		}
12902 	      else
12903 		{
12904 		  /*a967 */
12905 		  if ((scancfg.colormode != CM_GRAY)
12906 		      && (scancfg.colormode != CM_LINEART))
12907 		    sumatorio /= lf1a4[channel];
12908 		  else
12909 		    sumatorio /= lf1a4[scancfg.channel];
12910 
12911 		  sumatorio = min (sumatorio * 0x4000, 65535);
12912 
12913 		  if (myRegs[0x1bf] != 0x18)
12914 		    myCalib->black_shading[channel][lf13c] |=
12915 		      (0x140 -
12916 		       ((((myRegs[0x1bf] >> 3) & 3) *
12917 			 3) << 6)) & ((int) sumatorio);
12918 		  else
12919 		    myCalib->white_shading[channel][lf13c] =
12920 		      (unsigned short) sumatorio;
12921 		}
12922 
12923 	      /*a9fd */
12924 	      position++;
12925 	    }
12926 	  while (position < myWidth);
12927 	}
12928     }
12929   else
12930     {
12931       /*a6d9 */
12932       position = 0;
12933       sumatorio = 0;
12934       if (myWidth > 0)
12935 	{
12936 	  do
12937 	    {
12938 	      switch (scancfg.colormode)
12939 		{
12940 		case CM_GRAY:
12941 		case CM_LINEART:
12942 		  channel = 0;
12943 		  lf13c = position;
12944 		  break;
12945 		default:	/*CM_COLOR */
12946 		  if (scancfg.samplerate == PIXEL_RATE)
12947 		    {
12948 		      channel = position % bytes_per_pixel;
12949 		      lf13c = position / bytes_per_pixel;
12950 		    }
12951 		  else
12952 		    {
12953 		      channel = position / lf168;
12954 		      lf13c = position % lf168;
12955 		    }
12956 		  break;
12957 		}
12958 
12959 	      /*a743 */
12960 	      if (lf130 > 0)
12961 		memset (buffer1, 0, lf130 * sizeof (double));
12962 
12963 	      /*a761 */
12964 	      if (lf12c > 0)
12965 		{
12966 		  for (a = 0; a < lf12c; a++)
12967 		    buffer2[a] = (1 << scancfg.depth) - 1.0;
12968 		}
12969 
12970 	      /*a78f */
12971 	      myESI = 0;
12972 	      myEDI = 0;
12973 	      ptr = scanbuffer + position;
12974 	      myHeight = 0;
12975 
12976 	      if (otherheight > 0)
12977 		{
12978 		  do
12979 		    {
12980 		      myst = 0;
12981 		      for (a = 0; a < 4; a++)
12982 			myst += *(ptr + (a * myWidth));
12983 
12984 		      myEDI = 0;
12985 		      myst *= 0.25;
12986 		      if (myHeight < (otherheight - 4))
12987 			{
12988 			  if (myst < buffer2[myESI])
12989 			    {
12990 			      buffer2[myESI] = myst;
12991 			      if (lf12c > 0)
12992 				{
12993 				  for (a = 0; a < lf12c; a++)
12994 				    if (buffer2[myESI] < buffer2[a])
12995 				      myESI = a;
12996 				}
12997 			    }
12998 			  /*a820 */
12999 			  if (myst >= buffer1[myEDI])
13000 			    {
13001 			      buffer1[myEDI] = myst;
13002 			      if (lf130 > 0)
13003 				{
13004 				  for (a = 0; a < lf130; a++)
13005 				    if (buffer1[myEDI] >= buffer1[a])
13006 				      myEDI = a;
13007 				}
13008 			    }
13009 			  sumatorio += myst;
13010 			}
13011 		      else
13012 			{
13013 			  /*a853 */
13014 			  if (myHeight == (otherheight - 4))
13015 			    {
13016 			      if (lf12c > 0)
13017 				{
13018 				  for (a = 0; a < lf12c; a++)
13019 				    if (buffer2[myESI] >= buffer2[a])
13020 				      myESI = a;
13021 				}
13022 
13023 			      if (lf130 > 0)
13024 				{
13025 				  for (a = 0; a < lf130; a++)
13026 				    if (buffer1[myEDI] < buffer1[a])
13027 				      myEDI = a;
13028 				}
13029 			    }
13030 
13031 			  /*a895 */
13032 			  if (myst >= buffer2[myESI])
13033 			    {
13034 			      /*a89c */
13035 			      sumatorio -= buffer2[myESI];
13036 			      sumatorio += myst;
13037 			      buffer2[myESI] = myst;
13038 			      if (lf12c > 0)
13039 				{
13040 				  for (a = 0; a < lf12c; a++)
13041 				    if (buffer2[myESI] >= buffer2[a])
13042 				      myESI = a;
13043 				}
13044 			    }
13045 			  else
13046 			    {
13047 			      if (myst < buffer1[myEDI])
13048 				{
13049 				  sumatorio -= buffer1[myEDI];
13050 				  sumatorio += myst;
13051 				  buffer1[myEDI] = myst;
13052 
13053 				  if (lf130 > 0)
13054 				    {
13055 				      for (a = 0; a < lf130; a++)
13056 					if (buffer1[myEDI] < buffer1[a])
13057 					  myEDI = a;
13058 				    }
13059 				}
13060 			    }
13061 			}
13062 		      /*a901 */
13063 		      ptr += myWidth;
13064 		      myHeight++;
13065 		    }
13066 		  while (myHeight < otherheight);
13067 		}
13068 	      /*a924 */
13069 	      scancfg.ser = 0;
13070 	      scancfg.startpos = otherheight - 4;
13071 
13072 	      sumatorio /= scancfg.startpos;
13073 	      if (myCalib->shading_enabled != FALSE)
13074 		{
13075 		  /*a94a */
13076 		  myCalib->white_shading[channel][lf13c] =
13077 		    (unsigned short) sumatorio;
13078 		}
13079 	      else
13080 		{
13081 		  /*a967 */
13082 		  if ((scancfg.colormode != CM_GRAY)
13083 		      && (scancfg.colormode != CM_LINEART))
13084 		    sumatorio /= lf1a4[channel];
13085 		  else
13086 		    sumatorio /= lf1a4[scancfg.channel];
13087 
13088 		  sumatorio = min (sumatorio * 0x4000, 65535);
13089 
13090 		  if (myRegs[0x1bf] != 0x18)
13091 		    myCalib->black_shading[channel][lf13c] |=
13092 		      (0x140 -
13093 		       ((((myRegs[0x1bf] >> 3) & 0x03) *
13094 			 3) << 6)) & ((int) sumatorio);
13095 		  else
13096 		    myCalib->white_shading[channel][lf13c] =
13097 		      (unsigned short) sumatorio;
13098 		}
13099 	      /*a9fd */
13100 	      position++;
13101 	    }
13102 	  while (position < myWidth);
13103 	}
13104     }
13105 
13106   /*aa12 */
13107   if (RTS_Debug->SaveCalibFile != FALSE)
13108     {
13109       dbg_tiff_save ("whiteshading3.tiff",
13110 		     scancfg.coord.width,
13111 		     scancfg.coord.height,
13112 		     scancfg.depth,
13113 		     CM_COLOR,
13114 		     scancfg.resolution_x,
13115 		     scancfg.resolution_y,
13116 		     scanbuffer,
13117 		     (scancfg.coord.height + 16) * bytes_per_line);
13118     }
13119 
13120   free (buffer1);
13121   free (buffer2);
13122   free (scanbuffer);
13123 
13124   return OK;
13125 }
13126 
13127 static SANE_Int
Calib_BlackShading(struct st_device * dev,struct st_calibration_config * calibcfg,struct st_calibration * myCalib,SANE_Int gainmode)13128 Calib_BlackShading (struct st_device *dev,
13129 		    struct st_calibration_config *calibcfg,
13130 		    struct st_calibration *myCalib, SANE_Int gainmode)
13131 {
13132   /*
13133      gainmode  f8ec
13134      myCalib   f8e8
13135      calibcfg f8e4
13136    */
13137   SANE_Byte *myRegs;		/*f1bc */
13138   struct st_scanparams scancfg;	/*f020 */
13139   double shadingprediff[6];	/*f08c f094 f09c f0a4 f0ac f0b4 */
13140   double mylong;		/*f018 */
13141   double maxvalue;		/*eff8 */
13142   double sumatorio = 0.0;
13143   double myst;
13144   SANE_Int rst;
13145   SANE_Int a;
13146   SANE_Int mheight;		/*efe0 */
13147   SANE_Int current_line;	/*efe4 */
13148   SANE_Int bytes_per_line;	/*efd8 */
13149   SANE_Int position;		/*lefcc */
13150   SANE_Int leff0, lf010, lefd0;
13151   SANE_Byte *buffer;		/*efd4 */
13152   SANE_Byte buff2[256];		/*F0BC */
13153   SANE_Int buff3[0x8000];
13154   SANE_Byte *ptr;		/*f008 */
13155   SANE_Int my14b4;		/*f008 pisa ptr */
13156   SANE_Int biggest;		/*bx */
13157   SANE_Int lowest;		/*dx */
13158   SANE_Int lefdc;
13159   SANE_Int channel;
13160   SANE_Int smvalues[3];		/*f04c f04e f050 */
13161   double dbvalue[6];		/*lf05c lf060, lf064 lf068, lf06c lf070,
13162 				   lf074 lf078, lf07c lf080, lf084 lf088 */
13163 
13164   DBG (DBG_FNC, "> Calib_BlackShading(*calibcfg, *myCalib, gainmode=%i)\n",
13165        gainmode);
13166 
13167   rst = OK;
13168   myRegs = (SANE_Byte *) malloc (RT_BUFFER_LEN * sizeof (SANE_Byte));
13169   memcpy (myRegs, &calibdata->Regs, RT_BUFFER_LEN * sizeof (SANE_Byte));
13170   memcpy (&scancfg, &calibdata->scancfg, sizeof (struct st_scanparams));
13171 
13172   Lamp_SetGainMode (dev, myRegs, scancfg.resolution_x, gainmode);
13173 
13174   for (a = CL_RED; a <= CL_BLUE; a++)
13175     shadingprediff[a + 3] = calibcfg->BShadingPreDiff[a];
13176 
13177   if ((scan.scantype >= ST_NORMAL) && (scan.scantype <= ST_NEG))
13178     scancfg.coord.left += scan.ser;
13179 
13180   if ((scancfg.coord.width & 1) != 0)
13181     scancfg.coord.width++;
13182 
13183   scancfg.coord.top = 1;
13184   scancfg.depth = 8;
13185   scancfg.coord.height = calibcfg->BShadingHeight;
13186 
13187   if (scancfg.colormode != CM_COLOR)
13188     {
13189       bytes_per_line = scancfg.coord.width;
13190       leff0 = 0;
13191       lf010 = 1;
13192     }
13193   else
13194     {
13195       /*876c */
13196       bytes_per_line = scancfg.coord.width * 3;
13197       if (scancfg.samplerate == LINE_RATE)
13198 	{
13199 	  leff0 = scancfg.coord.width;
13200 	  lf010 = 1;
13201 	}
13202       else
13203 	{
13204 	  leff0 = 1;
13205 	  lf010 = 3;
13206 	}
13207     }
13208 
13209   scancfg.v157c = bytes_per_line;
13210   scancfg.bytesperline = bytes_per_line;
13211 
13212   mylong = 1 << (16 - scancfg.depth);
13213   if ((myRegs[0x1bf] & 0x18) != 0)
13214     mylong /= 1 << (((myRegs[0x1bf] >> 5) & 3) + 4);
13215 
13216   lefd0 =
13217     ((((myRegs[0x1bf] >> 3) & 2) << 8) -
13218      ((((myRegs[0x1bf] >> 3) & 1) * 3) << 6)) - 1;
13219 
13220   if (scancfg.depth >= 8)
13221     maxvalue = ((1 << (scancfg.depth - 8)) << 8) - 1;
13222   else
13223     maxvalue = (256 / (1 << (8 - scancfg.depth))) - 1;
13224 
13225   Calib_LoadCut (dev, &scancfg, scan.scantype, calibcfg);
13226   for (a = CL_RED; a <= CL_BLUE; a++)
13227     shadingprediff[a] = calibcfg->ShadingCut[a];
13228 
13229   if (calibcfg->BShadingOn == -1)
13230     {
13231       SANE_Int b, d;
13232       double e;
13233 
13234       for (a = CL_RED; a <= CL_BLUE; a++)
13235 	{
13236 	  myst = max (shadingprediff[a], 0);
13237 	  myst = (maxvalue >= myst) ? shadingprediff[a] : maxvalue;
13238 	  shadingprediff[a] = max (myst, 0);
13239 	}
13240 
13241       b = 0;
13242 
13243       while (b < bytes_per_line)
13244 	{
13245 	  if (scancfg.colormode != CM_COLOR)
13246 	    {
13247 	      channel = 0;
13248 	      d = b;
13249 	    }
13250 	  else
13251 	    {
13252 	      if (scancfg.samplerate == PIXEL_RATE)
13253 		{
13254 		  channel = (b % lf010) & 0xffff;
13255 		  d = (b / lf010) & 0xffff;
13256 		}
13257 	      else
13258 		{
13259 		  channel = (b / leff0) & 0xffff;
13260 		  d = (b % leff0) & 0xffff;
13261 		}
13262 	    }
13263 	  /*89d0 */
13264 	  e = min (lefd0, mylong * shadingprediff[channel]);
13265 	  myCalib->black_shading[channel][d] |= (unsigned short) e & 0xffff;
13266 	  b++;
13267 	}
13268 
13269       return OK;
13270     }
13271 
13272   /* Allocate buffer to read image */
13273   mheight = scancfg.coord.height;
13274   buffer =
13275     (SANE_Byte *) malloc (((scancfg.coord.height + 16) * bytes_per_line) *
13276 			  sizeof (SANE_Byte));
13277   if (buffer == NULL)
13278     return ERROR;
13279 
13280   /* Turn off lamp */
13281   Lamp_Status_Set (dev, NULL, FALSE, FLB_LAMP);
13282   usleep (200 * 1000);
13283 
13284   /* Scan image */
13285   myCalib->shading_enabled = FALSE;
13286   rst =
13287     RTS_GetImage (dev, myRegs, &scancfg, &calibdata->gain_offset, buffer,
13288 		  myCalib, 0x101, gainmode);
13289   if (rst == ERROR)
13290     {
13291       /*8ac2 */
13292       free (buffer);
13293       memcpy (&calibdata->Regs, myRegs, RT_BUFFER_LEN * sizeof (SANE_Byte));
13294       free (myRegs);
13295       return ERROR;
13296     }
13297 
13298   /* myRegs isn't going to be used anymore */
13299   free (myRegs);
13300   myRegs = NULL;
13301 
13302   /* Turn on lamp again */
13303   if (scan.scantype != ST_NORMAL)
13304     {
13305       Lamp_Status_Set (dev, NULL, FALSE, TMA_LAMP);
13306       usleep (1000 * 1000);
13307     }
13308   else
13309     Lamp_Status_Set (dev, NULL, TRUE, FLB_LAMP);
13310 
13311   /* Save buffer */
13312   if (RTS_Debug->SaveCalibFile != FALSE)
13313     {
13314       dbg_tiff_save ("blackshading.tiff",
13315 		     scancfg.coord.width,
13316 		     scancfg.coord.height,
13317 		     scancfg.depth,
13318 		     CM_COLOR,
13319 		     scancfg.resolution_x,
13320 		     scancfg.resolution_y,
13321 		     buffer, (scancfg.coord.height + 16) * bytes_per_line);
13322     }
13323 
13324   if (scancfg.depth > 8)
13325     {
13326       /*8bb2 */
13327       memset (&dbvalue, 0, 6 * sizeof (double));
13328       position = 0;
13329 
13330       if (bytes_per_line > 0)
13331 	{
13332 	  do
13333 	    {
13334 	      memset (&buff3, 0, 0x8000 * sizeof (SANE_Int));
13335 	      sumatorio = 0;
13336 	      ptr = buffer + position;
13337 	      current_line = 0;
13338 	      biggest = 0;
13339 	      lowest = (int) maxvalue;
13340 	      /* Toma los valores de una columna */
13341 	      if (mheight > 0)
13342 		{
13343 		  SANE_Int value;
13344 		  do
13345 		    {
13346 		      value = data_lsb_get (ptr, 2);
13347 		      biggest = max (biggest, value);
13348 		      if (current_line < mheight)
13349 			{
13350 			  sumatorio += value;
13351 			  lowest = min (lowest, value);
13352 			  biggest = max (biggest, value);
13353 
13354 			  buff3[value]++;
13355 			}
13356 		      else
13357 			{
13358 			  /*8cab */
13359 			  if (value > lowest)
13360 			    {
13361 			      buff3[lowest]--;
13362 			      buff3[value]++;
13363 			      sumatorio += value;
13364 			      sumatorio -= lowest;
13365 
13366 			      if (buff3[lowest] != 0)
13367 				{
13368 				  do
13369 				    {
13370 				      lowest++;
13371 				    }
13372 				  while (buff3[lowest] == 0);
13373 				}
13374 			    }
13375 			}
13376 		      /*8d0b */
13377 		      ptr += (bytes_per_line * 2);
13378 		      current_line++;
13379 		    }
13380 		  while (current_line < mheight);
13381 		}
13382 	      /*8d27 */
13383 	      sumatorio /= mheight;
13384 
13385 	      if (scancfg.colormode != CM_COLOR)
13386 		{
13387 		  channel = 0;
13388 		  lefdc = position;
13389 		}
13390 	      else
13391 		{
13392 		  /*8d5f */
13393 		  if (scancfg.samplerate == PIXEL_RATE)
13394 		    {
13395 		      channel = position % lf010;
13396 		      lefdc = (position / lf010) & 0xffff;
13397 		    }
13398 		  else
13399 		    {
13400 		      channel = position / leff0;
13401 		      lefdc = position % leff0;
13402 		    }
13403 		}
13404 
13405 	      dbvalue[channel] += sumatorio;
13406 	      if ((scancfg.colormode == CM_GRAY)
13407 		  || (scancfg.colormode == CM_LINEART))
13408 		sumatorio += shadingprediff[scancfg.channel];
13409 	      else
13410 		sumatorio += shadingprediff[channel];
13411 
13412 	      myst = min (max (0, sumatorio), maxvalue);
13413 
13414 	      dbvalue[channel + 3] = myst;
13415 
13416 	      if ((calibcfg->BShadingOn == 1) || (calibcfg->BShadingOn == 2))
13417 		{
13418 		  if (calibcfg->BShadingOn == 2)
13419 		    {
13420 		      myst -=
13421 			calibcfg->BRef[channel] * (1 << (scancfg.depth - 8));
13422 		      myst = max (myst, 0);
13423 		    }
13424 		  /*8e6d */
13425 		  myst *= mylong;
13426 		  myCalib->black_shading[channel][lefdc] = min (myst, lefd0);
13427 		}
13428 
13429 	      position++;
13430 	    }
13431 	  while (position < bytes_per_line);
13432 	}
13433     }
13434   else
13435     {
13436       /*8eb6 */
13437       memset (&dbvalue, 0, 6 * sizeof (double));
13438       position = 0;
13439 
13440       if (bytes_per_line > 0)
13441 	{
13442 	  do
13443 	    {
13444 	      memset (&buff2, 0, 256 * sizeof (SANE_Byte));
13445 	      sumatorio = 0;
13446 	      /* ptr points to the next position of the first line */
13447 	      ptr = buffer + position;
13448 	      biggest = 0;
13449 	      lowest = (int) maxvalue;
13450 	      current_line = 0;
13451 	      /* Toma los valores de una columna */
13452 	      if (mheight > 0)
13453 		{
13454 		  my14b4 = v14b4;
13455 		  do
13456 		    {
13457 		      biggest = max (biggest, *ptr);
13458 
13459 		      if (my14b4 == 0)
13460 			{
13461 			  /*8fd7 */
13462 			  if (current_line < mheight)
13463 			    {
13464 			      sumatorio += *ptr;
13465 
13466 			      lowest = min (lowest, *ptr);
13467 			      biggest = max (biggest, *ptr);
13468 
13469 			      buff2[*ptr]++;
13470 			    }
13471 			  else
13472 			    {
13473 			      /*9011 */
13474 			      if (*ptr > lowest)
13475 				{
13476 				  buff2[lowest]--;
13477 				  buff2[*ptr]++;
13478 				  sumatorio += *ptr;
13479 				  sumatorio -= lowest;
13480 
13481 				  if (buff2[lowest] != 0)
13482 				    {
13483 				      do
13484 					{
13485 					  lowest++;
13486 					}
13487 				      while (buff2[lowest] == 0);
13488 				    }
13489 				}
13490 			    }
13491 			}
13492 		      else
13493 			sumatorio += *ptr;
13494 		      /*9067 */
13495 		      /* Point to the next pixel under current line */
13496 		      ptr += bytes_per_line;
13497 		      current_line++;
13498 		    }
13499 		  while (current_line < mheight);
13500 		}
13501 
13502 	      /*908a */
13503 	      /* Calculates average of each column */
13504 	      sumatorio = sumatorio / mheight;
13505 
13506 	      if (scancfg.colormode != CM_COLOR)
13507 		{
13508 		  channel = 0;
13509 		  lefdc = position;
13510 		}
13511 	      else
13512 		{
13513 		  /*90c5 */
13514 		  if (scancfg.samplerate == PIXEL_RATE)
13515 		    {
13516 		      channel = position % lf010;
13517 		      lefdc = (position / lf010) & 0xffff;
13518 		    }
13519 		  else
13520 		    {
13521 		      /*90fb */
13522 		      channel = position / leff0;
13523 		      lefdc = position % leff0;
13524 		    }
13525 		}
13526 
13527 	      /*911f */
13528 	      dbvalue[channel] += sumatorio;
13529 	      if ((scancfg.colormode == CM_GRAY)
13530 		  || (scancfg.colormode == CM_LINEART))
13531 		sumatorio += shadingprediff[scancfg.channel];
13532 	      else
13533 		sumatorio += shadingprediff[channel];
13534 
13535 	      /*9151 */
13536 	      myst = min (max (0, sumatorio), maxvalue);
13537 
13538 	      /*9198 */
13539 	      if (position >= 3)
13540 		{
13541 		  double myst2;
13542 
13543 		  myst -= dbvalue[channel + 3];
13544 		  myst2 = myst;
13545 		  myst = min (myst, shadingprediff[channel + 3]);
13546 
13547 		  my14b4 = -shadingprediff[channel + 3];
13548 		  if (myst >= my14b4)
13549 		    myst = min (myst2, shadingprediff[channel + 3]);
13550 		  else
13551 		    myst = my14b4;
13552 
13553 		  myst += dbvalue[channel + 3];
13554 		}
13555 
13556 	      /*9203 */
13557 	      dbvalue[channel + 3] = myst;
13558 
13559 	      switch (calibcfg->BShadingOn)
13560 		{
13561 		case 1:
13562 		  myCalib->black_shading[channel][lefdc] |=
13563 		    (unsigned short) (((int) myst & 0xff) << 8) & 0xffff;
13564 		  break;
13565 		case 2:
13566 		  /*9268 */
13567 		  my14b4 =
13568 		    calibcfg->BRef[channel] / (1 << (8 - scancfg.depth));
13569 		  myst -= my14b4;
13570 		  myst = max (myst, 0);
13571 		  myst *= mylong;
13572 		  myCalib->black_shading[channel][lefdc] = min (myst, lefd0);
13573 		  break;
13574 		}
13575 
13576 	      /*92d8 */
13577 	      position++;
13578 	    }
13579 	  while (position < bytes_per_line);
13580 	}
13581     }
13582 
13583   /*9306 */
13584   if (calibcfg->BShadingOn == -2)
13585     {
13586       for (a = 0; a < 3; a++)
13587 	{
13588 	  dbvalue[a] =
13589 	    (dbvalue[a] / scancfg.coord.width) + calibcfg->ShadingCut[a];
13590 	  if (dbvalue[a] < 0)
13591 	    dbvalue[a] = 0;
13592 	  smvalues[a] = min ((int) (dbvalue[a] + 0.5) & 0xffff, maxvalue);
13593 	}
13594 
13595       if (scancfg.coord.width > 0)
13596 	{
13597 	  SANE_Int b, c;
13598 
13599 	  for (c = 0; c < scancfg.coord.width; c++)
13600 	    for (b = 0; b < 3; b++)
13601 	      myCalib->black_shading[b][c] |=
13602 		(unsigned short) min (smvalues[b] * mylong, lefd0);
13603 	}
13604     }
13605   /*9425 */
13606   free (buffer);
13607 
13608   return OK;
13609 }
13610 
13611 static SANE_Int
Calibration(struct st_device * dev,SANE_Byte * Regs,struct st_scanparams * scancfg,struct st_calibration * myCalib,SANE_Int value)13612 Calibration (struct st_device *dev, SANE_Byte * Regs,
13613 	     struct st_scanparams *scancfg, struct st_calibration *myCalib,
13614 	     SANE_Int value)
13615 {
13616   /*//SANE_Int Calibration([fa20]char *Regs, [fa24]struct st_scanparams *scancfg, [fa28]struct st_calibration myCalib, [fa2c]SANE_Int value)
13617    */
13618 
13619   struct st_calibration_config calibcfg;	/* f90c */
13620   SANE_Int a;
13621   SANE_Byte gainmode;
13622   SANE_Int lf900;
13623 
13624   DBG (DBG_FNC, "> Calibration\n");
13625   dbg_ScanParams (scancfg);
13626 
13627   value = value;		/*silence gcc */
13628 
13629   memcpy (&calibdata->Regs, Regs, sizeof (SANE_Byte) * RT_BUFFER_LEN);
13630 
13631   /*4213be8 */
13632   memset (&calibcfg, 0x30, sizeof (struct st_calibration_config));
13633   Calib_LoadConfig (dev, &calibcfg, scan.scantype, scancfg->resolution_x,
13634 		    scancfg->depth);
13635 
13636   memset (&calibdata->gain_offset, 0, sizeof (struct st_gain_offset));	/*[42b3654] */
13637   for (a = CL_RED; a <= CL_BLUE; a++)
13638     {
13639       myCalib->WRef[a] = calibcfg.WRef[a];
13640 
13641       calibdata->gain_offset.edcg1[a] = 256;
13642       calibdata->gain_offset.odcg1[a] = 256;
13643       calibdata->gain_offset.vgag1[a] = 4;
13644       calibdata->gain_offset.vgag2[a] = 4;
13645 
13646       /*3654|3656|3658
13647          365a|365c|365e
13648          3660|3662|3664
13649          3666|3668|366a
13650          366c|366d|366e
13651          366f|3670|3671
13652          3672|3673|3674 */
13653     }
13654 
13655   memcpy (&calibdata->scancfg, scancfg, sizeof (struct st_scanparams));
13656   gainmode = Lamp_GetGainMode (dev, scancfg->resolution_x, scan.scantype);	/* [lf904] = 1 */
13657 
13658   /* 3cf3 */
13659   myCalib->first_position = 1;
13660   myCalib->shading_type = 0;
13661   if (calibdata->scancfg.colormode == CM_LINEART)
13662     {
13663       calibdata->scancfg.colormode = CM_GRAY;
13664       calibcfg.GainTargetFactor = 1.3;
13665     }
13666 
13667   lf900 = OK;
13668   if (calibcfg.CalibPAGOn != 0)
13669     {
13670       if (Calib_PAGain (dev, &calibcfg, gainmode) != 0)
13671 	lf900 = ERROR;
13672     /*ERROR*/}
13673   else
13674     {
13675       /*3da7 */
13676       if ((calibdata->scancfg.colormode != CM_GRAY)
13677 	  && (calibdata->scancfg.colormode != CM_LINEART))
13678 	{
13679 	  for (a = CL_RED; a <= CL_BLUE; a++)
13680 	    calibdata->gain_offset.pag[a] = calibcfg.PAG[a];
13681 	}
13682       else
13683 	{
13684 	  /* 3dd3 */
13685 	  /* Default PAGain */
13686 	  if (calibdata->scancfg.channel > 2)
13687 	    calibdata->scancfg.channel = 0;
13688 
13689 	  for (a = CL_RED; a <= CL_BLUE; a++)
13690 	    calibdata->gain_offset.pag[a] =
13691 	      calibcfg.PAG[calibdata->scancfg.channel];
13692 	}
13693     }
13694 
13695   /* 3e01 */
13696   if (calibcfg.CalibOffset10n != 0)	  /*==2*/
13697     {
13698       /*v14b4=1  offset[CL_RED]=0x174  offset[CL_GREEN]=0x16d  offset[CL_BLUE]=0x160 */
13699       if ((v14b4 != 0) && (offset[CL_RED] != 0) && (offset[CL_GREEN] != 0)
13700 	  && (offset[CL_BLUE] != 0))
13701 	{
13702 	  for (a = CL_RED; a <= CL_BLUE; a++)
13703 	    {
13704 	      calibdata->gain_offset.edcg1[a] = offset[a];
13705 	      calibdata->gain_offset.odcg1[a] = offset[a];
13706 	    }
13707 	}
13708       else
13709 	{
13710 	  /* 3e84 */
13711 	  if ((calibcfg.CalibOffset10n > 0) && (calibcfg.CalibOffset10n < 4))
13712 	    {
13713 	      /*if (calibcfg.CalibOffset10n != 0) */
13714 	      if (calibcfg.CalibOffset10n == 3)
13715 		{
13716 		  lf900 = Calib_AdcOffsetRT (dev, &calibcfg, 1);
13717 		}
13718 	      else
13719 		{
13720 		  /* 3eb2 */
13721 		  /*falta codigo */
13722 		}
13723 	    }
13724 	}
13725     }
13726   else
13727     {
13728       /* 3faf */
13729       for (a = CL_RED; a <= CL_BLUE; a++)
13730 	{
13731 	  calibdata->gain_offset.edcg1[a] =
13732 	    abs (calibcfg.OffsetEven1[a] - 0x100);
13733 	  calibdata->gain_offset.odcg1[a] =
13734 	    abs (calibcfg.OffsetOdd1[a] - 0x100);
13735 	}
13736     }
13737 
13738   /* 3f13 3f0b */
13739   if ((gainmode != 0) && (calibcfg.CalibGain10n != 0))
13740     {
13741       /*gain[CL_RED]=0x17 gain[CL_GREEN]=0x12 gain[CL_BLUE]=0x17 */
13742       if ((v14b4 != 0) && (gain[CL_RED] != 0) && (gain[CL_GREEN] != 0)
13743 	  && (gain[CL_BLUE] != 0))
13744 	{
13745 	  for (a = CL_RED; a <= CL_BLUE; a++)
13746 	    calibdata->gain_offset.vgag1[a] = gain[a];
13747 	}
13748       else
13749 	{
13750 	  /*4025 */
13751 	  lf900 = Calib_AdcGain (dev, &calibcfg, 1, gainmode);
13752 
13753 	  if ((v14b4 != 0) && (lf900 == OK))
13754 	    GainOffset_Save (dev, &calibdata->gain_offset.edcg1[0],
13755 			     &calibdata->gain_offset.vgag1[0]);
13756 	}
13757     }
13758   else
13759     {
13760       /*4089 */
13761       for (a = CL_RED; a <= CL_BLUE; a++)
13762 	calibdata->gain_offset.vgag1[a] = calibcfg.Gain1[a];
13763     }
13764 
13765   /*40a5 */
13766   if ((gainmode != 0) && (calibcfg.CalibOffset20n != 0))
13767     {
13768       switch (calibcfg.CalibOffset20n)
13769 	{
13770 	case 3:
13771 	  lf900 = Calib_AdcOffsetRT (dev, &calibcfg, 2);
13772 	  break;
13773 	}
13774       /*4140 */
13775       /*falta codigo */
13776     }
13777   else
13778     {
13779       /*4162 */
13780       for (a = CL_RED; a <= CL_BLUE; a++)
13781 	{
13782 	  calibdata->gain_offset.edcg2[a] =
13783 	    abs (calibcfg.OffsetEven2[a] - 0x40);
13784 	  calibdata->gain_offset.odcg2[a] =
13785 	    abs (calibcfg.OffsetOdd2[a] - 0x40);
13786 	}
13787     }
13788 
13789   /*41d6 */
13790   if ((gainmode != 0) && (calibcfg.CalibGain20n != 0))
13791     {
13792       lf900 = Calib_AdcGain (dev, &calibcfg, 0, gainmode);
13793     }
13794   else
13795     {
13796       /*423c */
13797       for (a = CL_RED; a <= CL_BLUE; a++)
13798 	calibdata->gain_offset.vgag2[a] = calibcfg.Gain2[a];
13799     }
13800 
13801   /*4258 */
13802   if (calibcfg.TotShading != 0)
13803     {
13804       lf900 = Calib_BWShading (&calibcfg, myCalib, gainmode);
13805       /*falta codigo */
13806     }
13807   else
13808     {
13809       /*428f */
13810       if (gainmode != 0)
13811 	{
13812 	  if (calibcfg.BShadingOn != 0)
13813 	    lf900 = Calib_BlackShading (dev, &calibcfg, myCalib, gainmode);
13814 
13815 	  /*42fd */
13816 	  if ((lf900 != ERROR) && (calibcfg.WShadingOn != 0))
13817 	    {
13818 	      switch (calibcfg.WShadingOn)
13819 		{
13820 		default:
13821 		  break;
13822 		case 3:
13823 		  lf900 =
13824 		    Calib_WhiteShading_3 (dev, &calibcfg, myCalib, gainmode);
13825 		  break;
13826 		case 2:
13827 		  break;
13828 		}
13829 	    }
13830 	  else
13831 	    myCalib->shading_enabled = FALSE;
13832 	}
13833       else
13834 	myCalib->shading_enabled = FALSE;
13835     }
13836 
13837   /*43ca */
13838   memcpy (&myCalib->gain_offset, &calibdata->gain_offset,
13839 	  sizeof (struct st_gain_offset));
13840   memcpy (&mitabla2, &calibdata->gain_offset, sizeof (struct st_gain_offset));
13841 
13842   /*4424 */
13843   /* Park home after calibration */
13844   if (get_value (SCANINFO, PARKHOMEAFTERCALIB, TRUE, FITCALIBRATE) == FALSE)
13845     scan.ler -= calibcfg.WShadingHeight;
13846   else
13847     Head_ParkHome (dev, TRUE, dev->motorcfg->parkhomemotormove);
13848 
13849   return OK;
13850 }
13851 
13852 /*static void show_diff(struct st_device *dev, SANE_Byte *original)
13853 {
13854 	SANE_Byte *buffer = (SANE_Byte *)malloc(RT_BUFFER_LEN * sizeof(SANE_Byte));
13855 	SANE_Int a;
13856 
13857 	if ((buffer == NULL)||(original == NULL))
13858 		return;
13859 
13860 	if (RTS_ReadRegs(dev->usb_handle, buffer) != OK)
13861 	{
13862 		free(buffer);
13863 		return;
13864 	}
13865 
13866 	for (a = 0; a < RT_BUFFER_LEN; a++)
13867 	{
13868 		if ((original[a] & 0xff) != (buffer[a] & 0xff))
13869 		{
13870 			printf("%5i: %i -> %i\n", a, original[a] & 0xff, buffer[a] & 0xff);
13871 			original[a] = buffer[a] & 0xff;
13872 		}
13873 	}
13874 
13875 	free(buffer);
13876 } */
13877 
13878 static SANE_Int
Load_Constrains(struct st_device * dev)13879 Load_Constrains (struct st_device *dev)
13880 {
13881   SANE_Int rst = ERROR;
13882 
13883   if (dev->constrains != NULL)
13884     Free_Constrains (dev);
13885 
13886   DBG (DBG_FNC, "> Load_Constrains\n");
13887 
13888   dev->constrains =
13889     (struct st_constrains *) malloc (sizeof (struct st_constrains));
13890   if (dev->constrains != NULL)
13891     {
13892       cfg_constrains_get (dev->constrains);
13893       rst = OK;
13894     }
13895 
13896   return rst;
13897 }
13898 
13899 static SANE_Int
Constrains_Check(struct st_device * dev,SANE_Int Resolution,SANE_Int scantype,struct st_coords * mycoords)13900 Constrains_Check (struct st_device *dev, SANE_Int Resolution,
13901 		  SANE_Int scantype, struct st_coords *mycoords)
13902 {
13903   /*
13904      Constrains:
13905      100 dpi   850 x  1170   | 164 x 327
13906      300 dpi  2550 x  3510
13907      600 dpi  5100 x  7020
13908      1200 dpi 10200 x 14040
13909    */
13910 
13911   SANE_Int rst = ERROR;
13912 
13913   if (dev->constrains != NULL)
13914     {
13915       struct st_coords coords;
13916       struct st_coords *mc;
13917 
13918       if ((scantype < ST_NORMAL) || (scantype > ST_NEG))
13919 	scantype = ST_NORMAL;
13920 
13921       switch (scantype)
13922 	{
13923 	case ST_TA:
13924 	  mc = &dev->constrains->slide;
13925 	  break;
13926 	case ST_NEG:
13927 	  mc = &dev->constrains->negative;
13928 	  break;
13929 	default:
13930 	  mc = &dev->constrains->reflective;
13931 	  break;
13932 	}
13933 
13934       coords.left = MM_TO_PIXEL (mc->left, Resolution);
13935       coords.width = MM_TO_PIXEL (mc->width, Resolution);
13936       coords.top = MM_TO_PIXEL (mc->top, Resolution);
13937       coords.height = MM_TO_PIXEL (mc->height, Resolution);
13938 
13939       /* Check left and top */
13940       if (mycoords->left < 0)
13941 	mycoords->left = 0;
13942 
13943       mycoords->left += coords.left;
13944 
13945       if (mycoords->top < 0)
13946 	mycoords->top = 0;
13947 
13948       mycoords->top += coords.top;
13949 
13950       /* Check width and height */
13951       if ((mycoords->width < 0) || (mycoords->width > coords.width))
13952 	mycoords->width = coords.width;
13953 
13954       if ((mycoords->height < 0) || (mycoords->height > coords.height))
13955 	mycoords->height = coords.height;
13956 
13957       rst = OK;
13958     }
13959 
13960   DBG (DBG_FNC,
13961        "> Constrains_Check: Source=%s, Res=%i, LW=(%i,%i), TH=(%i,%i): %i\n",
13962        dbg_scantype (scantype), Resolution, mycoords->left, mycoords->width,
13963        mycoords->top, mycoords->height, rst);
13964 
13965   return rst;
13966 }
13967 
13968 static struct st_coords *
Constrains_Get(struct st_device * dev,SANE_Byte scantype)13969 Constrains_Get (struct st_device *dev, SANE_Byte scantype)
13970 {
13971   static struct st_coords *rst = NULL;
13972 
13973   if (dev->constrains != NULL)
13974     {
13975       switch (scantype)
13976 	{
13977 	case ST_TA:
13978 	  rst = &dev->constrains->slide;
13979 	  break;
13980 	case ST_NEG:
13981 	  rst = &dev->constrains->negative;
13982 	  break;
13983 	default:
13984 	  rst = &dev->constrains->reflective;
13985 	  break;
13986 	}
13987     }
13988 
13989   return rst;
13990 }
13991 
13992 static void
Free_Constrains(struct st_device * dev)13993 Free_Constrains (struct st_device *dev)
13994 {
13995   DBG (DBG_FNC, "> Free_Constrains\n");
13996 
13997   if (dev->constrains != NULL)
13998     {
13999       free (dev->constrains);
14000       dev->constrains = NULL;
14001     }
14002 }
14003 
14004 static void
RTS_DebugInit()14005 RTS_DebugInit ()
14006 {
14007   /* Default values */
14008   RTS_Debug->dev_model = HP3970;
14009 
14010   RTS_Debug->DumpShadingData = FALSE;
14011   RTS_Debug->SaveCalibFile = FALSE;
14012   RTS_Debug->ScanWhiteBoard = FALSE;
14013   RTS_Debug->EnableGamma = TRUE;
14014   RTS_Debug->use_fixed_pwm = TRUE;
14015   RTS_Debug->dmatransfersize = 0x80000;
14016   RTS_Debug->dmasetlength = 0x7c0000;
14017   RTS_Debug->dmabuffersize = 0x400000;
14018   RTS_Debug->usbtype = -1;
14019 
14020   /* Lamp settings */
14021   RTS_Debug->overdrive_flb = 10000;	/* msecs */
14022   RTS_Debug->overdrive_ta = 10000;	/* msecs */
14023 
14024   RTS_Debug->warmup = TRUE;
14025 
14026   /* Calibration settings */
14027   RTS_Debug->calibrate = FALSE;
14028   RTS_Debug->wshading = TRUE;
14029 }
14030 
14031 static void
RTS_Setup_Gamma(SANE_Byte * Regs,struct st_hwdconfig * hwdcfg)14032 RTS_Setup_Gamma (SANE_Byte * Regs, struct st_hwdconfig *hwdcfg)
14033 {
14034   DBG (DBG_FNC, "> RTS_Setup_Gamma(*Regs, *hwdcfg)\n");
14035 
14036   if ((hwdcfg != NULL) && (Regs != NULL))
14037     {
14038       if (hwdcfg->use_gamma_tables != FALSE)
14039 	{
14040 	  SANE_Int table_size;
14041 
14042 	  /* set set table size */
14043 	  data_bitset (&Regs[0x1d0], 0x0f, hwdcfg->gamma_tablesize);
14044 
14045 	  /* enable gamma correction */
14046 	  data_bitset (&Regs[0x1d0], 0x40, 1);
14047 
14048 
14049 	  switch (Regs[0x1d0] & 0x0c)
14050 	    {
14051 	    case 0:
14052 	      table_size = (Regs[0x1d0] & 1) | 0x0100;
14053 	      break;
14054 	    case 4:
14055 	      table_size = (Regs[0x1d0] & 1) | 0x0400;
14056 	      break;
14057 	    case 8:
14058 	      table_size = (Regs[0x1d0] & 1) | 0x1000;
14059 	      break;
14060 	    default:
14061 	      table_size = hwdcfg->startpos & 0xffff;
14062 	      break;
14063 	    }
14064 
14065 	  /* 5073 */
14066 	  /* points to red gamma table */
14067 	  data_wide_bitset (&Regs[0x1b4], 0x3fff, 0);
14068 
14069 	  /* points to green gamma table */
14070 	  data_wide_bitset (&Regs[0x1b6], 0x3fff, table_size);
14071 
14072 	  /* points to blue gamma table */
14073 	  data_wide_bitset (&Regs[0x1b8], 0x3fff, table_size * 2);
14074 
14075 	  v15f8 = (((table_size * 3) + 15) / 16) & 0xffff;
14076 	}
14077       else
14078 	{
14079 	  /* disable gamma correction */
14080 	  data_bitset (&Regs[0x1d0], 0x40, 0);
14081 	  v15f8 = 0;
14082 	}
14083     }
14084 }
14085 
14086 static SANE_Int
RTS_USBType(struct st_device * dev)14087 RTS_USBType (struct st_device *dev)
14088 {
14089   /* Gets USB type of this scanner */
14090 
14091   SANE_Int rst = ERROR;
14092   SANE_Byte data;
14093 
14094   DBG (DBG_FNC, "+ RTS_USBType\n");
14095 
14096   if (Read_Byte (dev->usb_handle, 0xfe11, &data) == OK)
14097     rst = (data & 1);
14098 
14099   DBG (DBG_FNC, "- RTS_USBType(void): %s\n",
14100        (rst == USB11) ? "USB1.1" : "USB2.0");
14101 
14102   return rst;
14103 }
14104 
14105 static SANE_Int
Init_Vars(void)14106 Init_Vars (void)
14107 {
14108   SANE_Int rst = OK;
14109 
14110   hp_gamma = malloc (sizeof (struct st_gammatables));
14111   if (hp_gamma != NULL)
14112     memset (hp_gamma, 0, sizeof (struct st_gammatables));
14113   else
14114     rst = ERROR;
14115 
14116   if (rst == OK)
14117     {
14118       RTS_Debug = malloc (sizeof (struct st_debug_opts));
14119       if (RTS_Debug != NULL)
14120 	memset (RTS_Debug, 0, sizeof (struct st_debug_opts));
14121       else
14122 	rst = ERROR;
14123     }
14124 
14125   if (rst == OK)
14126     {
14127       default_gain_offset = malloc (sizeof (struct st_gain_offset));
14128       if (default_gain_offset != NULL)
14129 	memset (default_gain_offset, 0, sizeof (struct st_gain_offset));
14130       else
14131 	rst = ERROR;
14132     }
14133 
14134   if (rst == OK)
14135     {
14136       calibdata = malloc (sizeof (struct st_calibration_data));
14137       if (calibdata != NULL)
14138 	memset (calibdata, 0, sizeof (struct st_calibration_data));
14139       else
14140 	rst = ERROR;
14141     }
14142 
14143   if (rst == OK)
14144     {
14145       wshading = malloc (sizeof (struct st_shading));
14146       if (wshading != NULL)
14147 	memset (wshading, 0, sizeof (struct st_shading));
14148       else
14149 	rst = ERROR;
14150     }
14151 
14152   waitforpwm = TRUE;
14153 
14154   use_gamma_tables = TRUE;
14155 
14156   if (rst == OK)
14157     RTS_DebugInit ();
14158   else
14159     Free_Vars ();
14160 
14161   return rst;
14162 }
14163 
14164 static void
Free_Vars(void)14165 Free_Vars (void)
14166 {
14167   if (RTS_Debug != NULL)
14168     {
14169       free (RTS_Debug);
14170       RTS_Debug = NULL;
14171     }
14172 
14173   if (hp_gamma != NULL)
14174     {
14175       free (hp_gamma);
14176       hp_gamma = NULL;
14177     }
14178 
14179   if (calibdata != NULL)
14180     {
14181       free (calibdata);
14182       calibdata = NULL;
14183     }
14184 
14185   if (wshading != NULL)
14186     {
14187       if (wshading->rates != NULL)
14188 	free (wshading->rates);
14189 
14190       free (wshading);
14191       wshading = NULL;
14192     }
14193 
14194   if (default_gain_offset != NULL)
14195     {
14196       free (default_gain_offset);
14197       default_gain_offset = NULL;
14198     }
14199 
14200 }
14201 
14202 static SANE_Int
Chipset_Reset(struct st_device * dev)14203 Chipset_Reset (struct st_device *dev)
14204 {
14205   SANE_Int rst;
14206 
14207   DBG (DBG_FNC, "+ Chipset_Reset:\n");
14208 
14209   /* I've found two ways to reset chipset. Next one will stay commented
14210      rst = ERROR;
14211      if (Read_Byte(dev->usb_handle, 0xe800, &data) == OK)
14212      {
14213      data |= 0x20;
14214      if (Write_Byte(dev->usb_handle, 0xe800, data) == OK)
14215      {
14216      data &= 0xdf;
14217      rst = Write_Byte(dev->usb_handle, 0xe800, data);
14218      }
14219      }
14220    */
14221 
14222   rst = IWrite_Buffer (dev->usb_handle, 0x0000, NULL, 0, 0x0801);
14223 
14224   DBG (DBG_FNC, "- Chipset_Reset: %i\n", rst);
14225 
14226   return rst;
14227 }
14228 
14229 static SANE_Int
RTS_DMA_Enable_Read(struct st_device * dev,SANE_Int dmacs,SANE_Int size,SANE_Int options)14230 RTS_DMA_Enable_Read (struct st_device *dev, SANE_Int dmacs, SANE_Int size,
14231 		     SANE_Int options)
14232 {
14233   SANE_Int rst = ERROR;
14234   SANE_Byte buffer[6];
14235 
14236   DBG (DBG_FNC,
14237        "+ RTS_DMA_Enable_Read(dmacs=0x%04x, size=%i, options=0x%06x)\n",
14238        dmacs, size, options);
14239 
14240   data_msb_set (&buffer[0], options, 3);
14241 
14242   /* buffer size divided by 2 (words count) */
14243   data_lsb_set (&buffer[3], size / 2, 3);
14244 
14245   rst = IWrite_Buffer (dev->usb_handle, dmacs, buffer, 6, 0x0400);
14246 
14247   DBG (DBG_FNC, "- RTS_DMA_Enable_Read: %i\n", rst);
14248 
14249   return rst;
14250 }
14251 
14252 static SANE_Int
RTS_DMA_Enable_Write(struct st_device * dev,SANE_Int dmacs,SANE_Int size,SANE_Int options)14253 RTS_DMA_Enable_Write (struct st_device *dev, SANE_Int dmacs, SANE_Int size,
14254 		      SANE_Int options)
14255 {
14256   SANE_Int rst = ERROR;
14257   SANE_Byte buffer[6];
14258 
14259   DBG (DBG_FNC,
14260        "+ RTS_DMA_Enable_Write(dmacs=0x%04x, size=%i, options=0x%06x)\n",
14261        dmacs, size, options);
14262 
14263   data_msb_set (&buffer[0], options, 3);
14264 
14265   /* buffer size divided by 2 (words count) */
14266   data_lsb_set (&buffer[3], size / 2, 3);
14267 
14268   rst = IWrite_Buffer (dev->usb_handle, dmacs, buffer, 6, 0x0401);
14269 
14270   DBG (DBG_FNC, "- RTS_DMA_Enable_Write: %i\n", rst);
14271 
14272   return rst;
14273 }
14274 
14275 static SANE_Int
RTS_DMA_Cancel(struct st_device * dev)14276 RTS_DMA_Cancel (struct st_device *dev)
14277 {
14278   SANE_Int rst;
14279 
14280   DBG (DBG_FNC, "+ RTS_DMA_Cancel:\n");
14281 
14282   rst = IWrite_Word (dev->usb_handle, 0x0000, 0, 0x0600);
14283 
14284   DBG (DBG_FNC, "- RTS_DMA_Cancel: %i\n", rst);
14285 
14286   return rst;
14287 }
14288 
14289 static SANE_Int
RTS_DMA_Reset(struct st_device * dev)14290 RTS_DMA_Reset (struct st_device *dev)
14291 {
14292   SANE_Int rst;
14293 
14294   DBG (DBG_FNC, "+ RTS_DMA_Reset:\n");
14295 
14296   rst = IWrite_Word (dev->usb_handle, 0x0000, 0x0000, 0x0800);
14297 
14298   DBG (DBG_FNC, "- RTS_DMA_Reset: %i\n", rst);
14299 
14300   return rst;
14301 }
14302 
14303 static SANE_Int
RTS_EEPROM_WriteByte(USB_Handle usb_handle,SANE_Int address,SANE_Byte data)14304 RTS_EEPROM_WriteByte (USB_Handle usb_handle, SANE_Int address, SANE_Byte data)
14305 {
14306   SANE_Int rst;
14307 
14308   DBG (DBG_FNC, "+ RTS_EEPROM_WriteByte(address=%04x, data=%i):\n", address,
14309        data);
14310 
14311   rst = IWrite_Byte (usb_handle, address, data, 0x200, 0x200);
14312 
14313   DBG (DBG_FNC, "- RTS_EEPROM_WriteByte: %i\n", rst);
14314 
14315   return rst;
14316 }
14317 
14318 static SANE_Int
RTS_EEPROM_ReadWord(USB_Handle usb_handle,SANE_Int address,SANE_Int * data)14319 RTS_EEPROM_ReadWord (USB_Handle usb_handle, SANE_Int address, SANE_Int * data)
14320 {
14321   SANE_Int rst;
14322 
14323   DBG (DBG_FNC, "+ RTS_EEPROM_ReadWord(address=%04x, data):\n", address);
14324 
14325   rst = IRead_Word (usb_handle, address, data, 0x200);
14326 
14327   DBG (DBG_FNC, "- RTS_EEPROM_ReadWord: %i\n", rst);
14328 
14329   return rst;
14330 }
14331 
14332 static SANE_Int
RTS_EEPROM_ReadByte(USB_Handle usb_handle,SANE_Int address,SANE_Byte * data)14333 RTS_EEPROM_ReadByte (USB_Handle usb_handle, SANE_Int address,
14334 		     SANE_Byte * data)
14335 {
14336   SANE_Int rst;
14337 
14338   DBG (DBG_FNC, "+ RTS_EEPROM_ReadByte(address=%04x, data):\n", address);
14339 
14340   rst = IRead_Byte (usb_handle, address, data, 0x200);
14341 
14342   DBG (DBG_FNC, "- RTS_EEPROM_ReadByte: %i\n", rst);
14343 
14344   return rst;
14345 }
14346 
14347 static SANE_Int
RTS_EEPROM_WriteWord(USB_Handle usb_handle,SANE_Int address,SANE_Int data)14348 RTS_EEPROM_WriteWord (USB_Handle usb_handle, SANE_Int address, SANE_Int data)
14349 {
14350   SANE_Int rst;
14351 
14352   DBG (DBG_FNC, "+ RTS_EEPROM_WriteWord(address=%04x, data=%i):\n", address,
14353        data);
14354 
14355   rst = IWrite_Word (usb_handle, address, data, 0x0200);
14356 
14357   DBG (DBG_FNC, "- RTS_EEPROM_WriteWord: %i\n", rst);
14358 
14359   return rst;
14360 }
14361 
14362 static SANE_Int
RTS_EEPROM_ReadInteger(USB_Handle usb_handle,SANE_Int address,SANE_Int * data)14363 RTS_EEPROM_ReadInteger (USB_Handle usb_handle, SANE_Int address,
14364 			SANE_Int * data)
14365 {
14366   SANE_Int rst;
14367 
14368   DBG (DBG_FNC, "+ RTS_EEPROM_ReadInteger(address=%04x, data):\n", address);
14369 
14370   rst = IRead_Integer (usb_handle, address, data, 0x200);
14371 
14372   DBG (DBG_FNC, "- RTS_EEPROM_ReadInteger: %i\n", rst);
14373 
14374   return rst;
14375 }
14376 
14377 static SANE_Int
RTS_EEPROM_WriteInteger(USB_Handle usb_handle,SANE_Int address,SANE_Int data)14378 RTS_EEPROM_WriteInteger (USB_Handle usb_handle, SANE_Int address,
14379 			 SANE_Int data)
14380 {
14381   SANE_Int rst;
14382 
14383   DBG (DBG_FNC, "+ RTS_EEPROM_WriteInteger(address=%04x, data):\n", address);
14384 
14385   rst = IWrite_Integer (usb_handle, address, data, 0x200);
14386 
14387   DBG (DBG_FNC, "- RTS_EEPROM_WriteInteger: %i\n", rst);
14388 
14389   return rst;
14390 }
14391 
14392 static SANE_Int
RTS_EEPROM_WriteBuffer(USB_Handle usb_handle,SANE_Int address,SANE_Byte * data,SANE_Int size)14393 RTS_EEPROM_WriteBuffer (USB_Handle usb_handle, SANE_Int address,
14394 			SANE_Byte * data, SANE_Int size)
14395 {
14396   SANE_Int rst;
14397 
14398   DBG (DBG_FNC, "+ RTS_EEPROM_WriteBuffer(address=%04x, data, size=%i):\n",
14399        address, size);
14400 
14401   rst = IWrite_Buffer (usb_handle, address, data, size, 0x200);
14402 
14403   DBG (DBG_FNC, "- RTS_EEPROM_WriteBuffer: %i\n", rst);
14404 
14405   return rst;
14406 }
14407 
14408 static void
WShading_Emulate(SANE_Byte * buffer,SANE_Int * chnptr,SANE_Int size,SANE_Int depth)14409 WShading_Emulate (SANE_Byte * buffer, SANE_Int * chnptr, SANE_Int size,
14410 		  SANE_Int depth)
14411 {
14412   if ((wshading->rates != NULL) && (chnptr != NULL))
14413     {
14414       if (*chnptr < wshading->count)
14415 	{
14416 	  double maxvalue, chncolor;
14417 	  SANE_Int chnsize;
14418 	  SANE_Int pos;
14419 	  SANE_Int icolor;
14420 
14421 	  maxvalue = (1 << depth) - 1;
14422 	  chnsize = (depth > 8) ? 2 : 1;
14423 
14424 	  pos = 0;
14425 	  while (pos < size)
14426 	    {
14427 	      /* get channel color */
14428 	      chncolor = data_lsb_get (buffer + pos, chnsize);
14429 
14430 	      /* apply shading coefficient */
14431 	      chncolor *= wshading->rates[*chnptr];
14432 
14433 	      /* care about limits */
14434 	      chncolor = min (chncolor, maxvalue);
14435 
14436 	      /* save color */
14437 	      icolor = chncolor;
14438 	      data_lsb_set (buffer + pos, icolor, chnsize);
14439 
14440 	      *chnptr = *chnptr + 1;
14441 	      if (*chnptr >= wshading->count)
14442 		*chnptr = 0;
14443 
14444 	      pos += chnsize;
14445 	    }
14446 	}
14447     }
14448 }
14449 
14450 static SANE_Int
WShading_Calibrate(struct st_device * dev,SANE_Byte * Regs,struct st_calibration * myCalib,struct st_scanparams * scancfg)14451 WShading_Calibrate (struct st_device *dev, SANE_Byte * Regs,
14452 		    struct st_calibration *myCalib,
14453 		    struct st_scanparams *scancfg)
14454 {
14455   struct st_calibration_config *calibcfg;
14456   struct st_gain_offset myCalibTable;
14457   struct st_scanparams *myscancfg;
14458   SANE_Byte *myRegs;		/*f1bc */
14459   SANE_Int bytes_per_line;
14460   /**/ SANE_Int x, y, a, C;
14461   SANE_Byte *pattern;		/*f164 */
14462   double sumatorio;
14463   SANE_Int gainmode;
14464   SANE_Int rst;
14465   SANE_Byte *avg_colors;
14466 
14467   DBG (DBG_FNC, "> WShading_Calibrate(*myCalib)\n");
14468 
14469   memset (&myCalibTable, 0, sizeof (struct st_gain_offset));
14470   for (C = CL_RED; C <= CL_BLUE; C++)
14471     {
14472       myCalibTable.pag[C] = 3;
14473       myCalibTable.vgag1[C] = 4;
14474       myCalibTable.vgag2[C] = 4;
14475     }
14476 
14477   calibcfg =
14478     (struct st_calibration_config *)
14479     malloc (sizeof (struct st_calibration_config));
14480   memset (calibcfg, 0x30, sizeof (struct st_calibration_config));
14481 
14482   myscancfg = (struct st_scanparams *) malloc (sizeof (struct st_scanparams));
14483   memcpy (myscancfg, scancfg, sizeof (struct st_scanparams));
14484 
14485   myRegs = (SANE_Byte *) malloc (RT_BUFFER_LEN * sizeof (SANE_Byte));
14486   memcpy (myRegs, Regs, RT_BUFFER_LEN * sizeof (SANE_Byte));
14487 
14488   Calib_LoadConfig (dev, calibcfg, scan.scantype, myscancfg->resolution_x,
14489 		    myscancfg->depth);
14490   gainmode = Lamp_GetGainMode (dev, myscancfg->resolution_x, scan.scantype);
14491 
14492   Lamp_SetGainMode (dev, myRegs, myscancfg->resolution_x, gainmode);
14493 
14494   rst = OK;
14495 
14496   switch (scan.scantype)
14497     {
14498     case ST_NORMAL:
14499       /*a184 */
14500       myscancfg->coord.left += scan.ser;
14501       myscancfg->coord.width &= 0xffff;
14502       break;
14503     case ST_TA:
14504     case ST_NEG:
14505       myscancfg->coord.left += scan.ser;
14506       break;
14507     }
14508 
14509   /*a11b */
14510   if ((myscancfg->coord.width & 1) != 0)
14511     myscancfg->coord.width++;
14512 
14513   myscancfg->coord.top = 1;
14514   myscancfg->coord.height = calibcfg->WShadingHeight;
14515 
14516   myscancfg->sensorresolution = 0;
14517 
14518   bytes_per_line =
14519     myscancfg->coord.width * (((myscancfg->colormode == CM_COLOR) ? 3 : 1) *
14520 			      ((myscancfg->depth > 8) ? 2 : 1));
14521 
14522   /*a1e8 */
14523   myscancfg->v157c = bytes_per_line;
14524   myscancfg->bytesperline = bytes_per_line;
14525 
14526   /* allocate space for pattern */
14527   pattern =
14528     (SANE_Byte *) malloc (((myscancfg->coord.height) * bytes_per_line) *
14529 			  sizeof (SANE_Byte));
14530   if (pattern == NULL)
14531     return ERROR;
14532 
14533   /* Scan image */
14534   myCalib->shading_enabled = FALSE;
14535   rst =
14536     RTS_GetImage (dev, myRegs, myscancfg, &myCalibTable, pattern, myCalib,
14537 		  0x20000000, gainmode);
14538 
14539   if (rst != ERROR)
14540     {
14541       SANE_Int chn;
14542       double colors[3] = { 0, 0, 0 };
14543       double prueba;
14544       SANE_Int data;
14545       SANE_Int bytes_per_channel;
14546 
14547       bytes_per_channel = (myscancfg->depth > 8) ? 2 : 1;
14548 
14549       avg_colors = (SANE_Byte *) malloc (sizeof (SANE_Byte) * bytes_per_line);
14550 
14551       if (avg_colors != NULL)
14552 	{
14553 	  wshading->ptr = 0;
14554 	  wshading->count = bytes_per_line / bytes_per_channel;
14555 
14556 	  if (wshading->rates != NULL)
14557 	    {
14558 	      free (wshading->rates);
14559 	      wshading->rates = NULL;
14560 	    }
14561 	  wshading->rates =
14562 	    (double *) malloc (sizeof (double) * wshading->count);
14563 
14564 	  chn = 0;
14565 	  for (x = 0; x < wshading->count; x++)
14566 	    {
14567 	      sumatorio = 0;
14568 
14569 	      for (y = 0; y < myscancfg->coord.height; y++)
14570 		{
14571 		  data =
14572 		    data_lsb_get (pattern +
14573 				  ((x * bytes_per_channel) +
14574 				   (bytes_per_line * y)), bytes_per_channel);
14575 		  sumatorio += data;
14576 		}
14577 
14578 	      sumatorio /= myscancfg->coord.height;
14579 	      a = sumatorio;
14580 	      colors[chn] = max (colors[chn], sumatorio);
14581 	      chn++;
14582 	      if (chn > 2)
14583 		chn = 0;
14584 
14585 	      data_lsb_set (avg_colors + (x * bytes_per_channel), a,
14586 			    bytes_per_channel);
14587 	    }
14588 
14589 	  DBG (DBG_FNC, " -> max colors RGB= %f %f %f\n", colors[0],
14590 	       colors[1], colors[2]);
14591 
14592 	  chn = 0;
14593 	  for (x = 0; x < wshading->count; x++)
14594 	    {
14595 	      data =
14596 		data_lsb_get (avg_colors + (x * bytes_per_channel),
14597 			      bytes_per_channel);
14598 	      prueba = data;
14599 	      *(wshading->rates + x) = colors[chn] / prueba;
14600 	      chn++;
14601 	      if (chn > 2)
14602 		chn = 0;
14603 	    }
14604 	}
14605 
14606       if (RTS_Debug->SaveCalibFile != FALSE)
14607 	{
14608 	  dbg_tiff_save ("whiteshading_jkd.tiff",
14609 			 myscancfg->coord.width,
14610 			 myscancfg->coord.height,
14611 			 myscancfg->depth,
14612 			 CM_COLOR,
14613 			 scancfg->resolution_x,
14614 			 scancfg->resolution_y,
14615 			 pattern, (myscancfg->coord.height) * bytes_per_line);
14616 	}
14617 
14618 #ifdef developing
14619       {
14620 	FILE *archivo;
14621 	char texto[1024];
14622 
14623 	/* apply correction to the pattern to see the result */
14624 	chn = 0;
14625 	for (x = 0; x < myscancfg->coord.height * wshading->count; x++)
14626 	  {
14627 	    data =
14628 	      data_lsb_get (pattern + (x * bytes_per_channel),
14629 			    bytes_per_channel);
14630 	    sumatorio = data;
14631 	    sumatorio *= wshading->rates[chn];
14632 	    if (sumatorio > ((1 << myscancfg->depth) - 1))
14633 	      sumatorio = (1 << myscancfg->depth) - 1;
14634 
14635 	    a = sumatorio;
14636 	    data_lsb_set (pattern + (x * bytes_per_channel), a,
14637 			  bytes_per_channel);
14638 
14639 	    chn++;
14640 	    if (chn == wshading->count)
14641 	      chn = 0;
14642 	  }
14643 
14644 	/* save corrected pattern */
14645 	dbg_tiff_save ("onwhiteshading_jkd.tiff",
14646 		       myscancfg->coord.width,
14647 		       myscancfg->coord.height,
14648 		       myscancfg->depth,
14649 		       CM_COLOR,
14650 		       scancfg->resolution_x,
14651 		       scancfg->resolution_y,
14652 		       pattern, (myscancfg->coord.height) * bytes_per_line);
14653 
14654 	/* export coefficients */
14655 	archivo = fopen ("wShading.txt", "w");
14656 	for (x = 0; x < wshading->count; x++)
14657 	  {
14658 	    snprintf (texto, 1024, "%f", wshading->rates[x]);
14659 	    fprintf (archivo, "%s\n", texto);
14660 	  }
14661 
14662 	fclose (archivo);
14663       }
14664 #endif
14665     }
14666 
14667   free (pattern);
14668 
14669   return OK;
14670 }
14671 
14672 #ifdef developing
14673 static SANE_Int
motor_pos(struct st_device * dev,SANE_Byte * Regs,struct st_calibration * myCalib,struct st_scanparams * scancfg)14674 motor_pos (struct st_device *dev, SANE_Byte * Regs,
14675 	   struct st_calibration *myCalib, struct st_scanparams *scancfg)
14676 {
14677   struct st_calibration_config *calibcfg;
14678   struct st_gain_offset myCalibTable;
14679   struct st_scanparams *myscancfg;
14680   SANE_Byte *myRegs;		/*f1bc */
14681   SANE_Int bytes_per_line;
14682   /**/ SANE_Int a, C;
14683   SANE_Byte *scanbuffer;	/*f164 */
14684   SANE_Int gainmode;
14685   SANE_Int rst;
14686 
14687   DBG (DBG_FNC, "> Calib_test(*myCalib)\n");
14688 
14689   memset (&myCalibTable, 0, sizeof (struct st_gain_offset));
14690 
14691   calibcfg =
14692     (struct st_calibration_config *)
14693     malloc (sizeof (struct st_calibration_config));
14694   memset (calibcfg, 0x30, sizeof (struct st_calibration_config));
14695 
14696   myscancfg = (struct st_scanparams *) malloc (sizeof (struct st_scanparams));
14697   memcpy (myscancfg, scancfg, sizeof (struct st_scanparams));
14698 
14699   myRegs = (SANE_Byte *) malloc (RT_BUFFER_LEN * sizeof (SANE_Byte));
14700   memcpy (myRegs, Regs, RT_BUFFER_LEN * sizeof (SANE_Byte));
14701 
14702   Calib_LoadConfig (dev, calibcfg, scan.scantype, myscancfg->resolution_x,
14703 		    myscancfg->depth);
14704   gainmode = Lamp_GetGainMode (dev, myscancfg->resolution_x, scan.scantype);
14705 
14706   Lamp_SetGainMode (dev, myRegs, myscancfg->resolution_x, gainmode);
14707 
14708   rst = OK;
14709 
14710   switch (scan.scantype)
14711     {
14712     case ST_NORMAL:
14713       /*a184 */
14714       myscancfg->coord.left += scan.ser;
14715       myscancfg->coord.width &= 0xffff;
14716       break;
14717     case ST_TA:
14718     case ST_NEG:
14719       myscancfg->coord.left += scan.ser;
14720       break;
14721     }
14722 
14723   /*a11b */
14724   if ((myscancfg->coord.width & 1) != 0)
14725     myscancfg->coord.width++;
14726 
14727   myscancfg->coord.top = 100;
14728   myscancfg->coord.height = 30;
14729 
14730   bytes_per_line = myscancfg->coord.width * 3;
14731 
14732   /*a1e8 */
14733   myscancfg->v157c = bytes_per_line;
14734   myscancfg->bytesperline = bytes_per_line;
14735 
14736   scanbuffer =
14737     (SANE_Byte *) malloc (((myscancfg->coord.height + 16) * bytes_per_line) *
14738 			  sizeof (SANE_Byte));
14739   if (scanbuffer == NULL)
14740     return ERROR;
14741 
14742   /* Scan image */
14743   myCalib->shading_enabled = FALSE;
14744   /*Head_Relocate(dev, dev->motorcfg->highspeedmotormove, MTR_FORWARD, 5500); */
14745 
14746   for (a = 0; a < 10; a++)
14747     {
14748       for (C = CL_RED; C <= CL_BLUE; C++)
14749 	{
14750 	  myCalibTable.pag[C] = 3;
14751 	  myCalibTable.vgag1[C] = 4;
14752 	  myCalibTable.vgag2[C] = 4;
14753 	  myCalibTable.edcg1[C] = a * 20;
14754 	}
14755 
14756       dbg_ScanParams (myscancfg);
14757 
14758       Head_Relocate (dev, dev->motorcfg->highspeedmotormove, MTR_FORWARD,
14759 		     5000);
14760       rst =
14761 	RTS_GetImage (dev, myRegs, myscancfg, &myCalibTable, scanbuffer,
14762 		      myCalib, 0x20000000, gainmode);
14763       Head_ParkHome (dev, TRUE, dev->motorcfg->parkhomemotormove);
14764 
14765       if (rst != ERROR)
14766 	{
14767 	  char name[30];
14768 	  snprintf (name, 30, "calibtest-%i.tiff", a);
14769 	  dbg_tiff_save (name,
14770 			 myscancfg->coord.width,
14771 			 myscancfg->coord.height,
14772 			 myscancfg->depth,
14773 			 CM_COLOR,
14774 			 myscancfg->resolution_x,
14775 			 myscancfg->resolution_y,
14776 			 scanbuffer,
14777 			 (myscancfg->coord.height + 16) * bytes_per_line);
14778 	}
14779     }
14780 
14781   free (scanbuffer);
14782 
14783   exit (0);
14784   return OK;
14785 }
14786 
14787 static SANE_Int
hp4370_prueba(struct st_device * dev)14788 hp4370_prueba (struct st_device *dev)
14789 {
14790   SANE_Int rst;
14791   SANE_Int data = 0x0530, a;
14792   SANE_Int transferred;
14793   SANE_Byte buffer[512];
14794 
14795   for (a = 0; a < 256; a++)
14796     data_lsb_set (buffer + (a * 2), 0x9d7, 2);
14797 
14798   rst = IWrite_Word (dev->usb_handle, 0x0000, data, 0x0800);
14799   RTS_DMA_Enable_Write (dev, 0x4, 512, 0);
14800   Bulk_Operation (dev, BLK_WRITE, 512, buffer, &transferred);
14801 
14802   return rst;
14803 }
14804 
14805 static SANE_Int
Calib_BlackShading_jkd(struct st_device * dev,SANE_Byte * Regs,struct st_calibration * myCalib,struct st_scanparams * scancfg)14806 Calib_BlackShading_jkd (struct st_device *dev, SANE_Byte * Regs,
14807 			struct st_calibration *myCalib,
14808 			struct st_scanparams *scancfg)
14809 {
14810   struct st_calibration_config *calibcfg;
14811   struct st_gain_offset myCalibTable;
14812   struct st_scanparams *myscancfg;
14813   SANE_Byte *myRegs;		/*f1bc */
14814   SANE_Int bytes_per_line;
14815   /**/ SANE_Int x, y, a, C;
14816   SANE_Byte *scanbuffer;	/*f164 */
14817   double sumatorio;
14818   SANE_Int gainmode;
14819   SANE_Int rst;
14820 
14821   DBG (DBG_FNC, "> Calib_BlackShading_jkd(*myCalib)\n");
14822 
14823   memset (&myCalibTable, 0, sizeof (struct st_gain_offset));
14824   for (C = CL_RED; C <= CL_BLUE; C++)
14825     {
14826       myCalibTable.pag[C] = 3;
14827       myCalibTable.vgag1[C] = 4;
14828       myCalibTable.vgag2[C] = 4;
14829     }
14830 
14831   calibcfg =
14832     (struct st_calibration_config *)
14833     malloc (sizeof (struct st_calibration_config));
14834   memset (calibcfg, 0x30, sizeof (struct st_calibration_config));
14835 
14836   myscancfg = (struct st_scanparams *) malloc (sizeof (struct st_scanparams));
14837   memcpy (myscancfg, scancfg, sizeof (struct st_scanparams));
14838 
14839   myRegs = (SANE_Byte *) malloc (RT_BUFFER_LEN * sizeof (SANE_Byte));
14840   memcpy (myRegs, Regs, RT_BUFFER_LEN * sizeof (SANE_Byte));
14841 
14842   Calib_LoadConfig (dev, calibcfg, scan.scantype, myscancfg->resolution_x,
14843 		    myscancfg->depth);
14844   gainmode = Lamp_GetGainMode (dev, myscancfg->resolution_x, scan.scantype);
14845 
14846   Lamp_SetGainMode (dev, myRegs, myscancfg->resolution_x, gainmode);
14847 
14848   rst = OK;
14849 
14850   switch (scan.scantype)
14851     {
14852     case ST_NORMAL:
14853       /*a184 */
14854       myscancfg->coord.left += scan.ser;
14855       myscancfg->coord.width &= 0xffff;
14856       break;
14857     case ST_TA:
14858     case ST_NEG:
14859       myscancfg->coord.left += scan.ser;
14860       break;
14861     }
14862 
14863   /*a11b */
14864   if ((myscancfg->coord.width & 1) != 0)
14865     myscancfg->coord.width++;
14866 
14867   myscancfg->coord.top = 1;
14868   myscancfg->coord.height = calibcfg->BShadingHeight;
14869 
14870   bytes_per_line = myscancfg->coord.width * 3;
14871 
14872   /*a1e8 */
14873   myscancfg->v157c = bytes_per_line;
14874   myscancfg->bytesperline = bytes_per_line;
14875 
14876   scanbuffer =
14877     (SANE_Byte *) malloc (((myscancfg->coord.height + 16) * bytes_per_line) *
14878 			  sizeof (SANE_Byte));
14879   if (scanbuffer == NULL)
14880     return ERROR;
14881 
14882   /* Turn off lamp */
14883   Lamp_Status_Set (dev, NULL, FALSE, FLB_LAMP);
14884   usleep (200 * 1000);
14885 
14886   /* Scan image */
14887   myCalib->shading_enabled = FALSE;
14888   rst =
14889     RTS_GetImage (dev, myRegs, myscancfg, &myCalibTable, scanbuffer, myCalib,
14890 		  0x101, gainmode);
14891 
14892   /* Turn on lamp again */
14893   if (scan.scantype != ST_NORMAL)
14894     {
14895       Lamp_Status_Set (dev, NULL, FALSE, TMA_LAMP);
14896       usleep (1000 * 1000);
14897     }
14898   else
14899     Lamp_Status_Set (dev, NULL, TRUE, FLB_LAMP);
14900 
14901   if (rst != ERROR)
14902     {
14903       jkd_black = (SANE_Byte *) malloc (bytes_per_line);
14904 
14905       if (jkd_black != NULL)
14906 	{
14907 	  jkd_blackbpl = bytes_per_line;
14908 
14909 	  for (x = 0; x < bytes_per_line; x++)
14910 	    {
14911 	      sumatorio = 0;
14912 
14913 	      for (y = 0; y < myscancfg->coord.height + 16; y++)
14914 		sumatorio += scanbuffer[x + (bytes_per_line * y)];
14915 
14916 	      sumatorio /= myscancfg->coord.height + 16;
14917 	      a = sumatorio;
14918 	      *(jkd_black + x) = _B0 (a);
14919 	    }
14920 	}
14921 
14922       /*if (RTS_Debug->SaveCalibFile != FALSE) */
14923       {
14924 	dbg_tiff_save ("blackshading_jkd.tiff",
14925 		       myscancfg->coord.width,
14926 		       myscancfg->coord.height,
14927 		       myscancfg->depth,
14928 		       CM_COLOR,
14929 		       myscancfg->resolution_x,
14930 		       myscancfg->resolution_y,
14931 		       scanbuffer,
14932 		       (myscancfg->coord.height + 16) * bytes_per_line);
14933       }
14934     }
14935 
14936   free (scanbuffer);
14937 
14938   return OK;
14939 }
14940 
14941 static SANE_Int
Calib_test(struct st_device * dev,SANE_Byte * Regs,struct st_calibration * myCalib,struct st_scanparams * scancfg)14942 Calib_test (struct st_device *dev, SANE_Byte * Regs,
14943 	    struct st_calibration *myCalib, struct st_scanparams *scancfg)
14944 {
14945   struct st_calibration_config *calibcfg;
14946   struct st_gain_offset myCalibTable;
14947   struct st_scanparams *myscancfg;
14948   SANE_Byte *myRegs;		/*f1bc */
14949   SANE_Int bytes_per_line;
14950   /**/ SANE_Int a, C;
14951   SANE_Byte *scanbuffer;	/*f164 */
14952   SANE_Int gainmode;
14953   SANE_Int rst;
14954 
14955   DBG (DBG_FNC, "> Calib_test(*myCalib)\n");
14956 
14957   memset (&myCalibTable, 0, sizeof (struct st_gain_offset));
14958 
14959   calibcfg =
14960     (struct st_calibration_config *)
14961     malloc (sizeof (struct st_calibration_config));
14962   memset (calibcfg, 0x30, sizeof (struct st_calibration_config));
14963 
14964   myscancfg = (struct st_scanparams *) malloc (sizeof (struct st_scanparams));
14965   memcpy (myscancfg, scancfg, sizeof (struct st_scanparams));
14966 
14967   myRegs = (SANE_Byte *) malloc (RT_BUFFER_LEN * sizeof (SANE_Byte));
14968   memcpy (myRegs, Regs, RT_BUFFER_LEN * sizeof (SANE_Byte));
14969 
14970   Calib_LoadConfig (dev, calibcfg, scan.scantype, myscancfg->resolution_x,
14971 		    myscancfg->depth);
14972   gainmode = Lamp_GetGainMode (dev, myscancfg->resolution_x, scan.scantype);
14973 
14974   Lamp_SetGainMode (dev, myRegs, myscancfg->resolution_x, gainmode);
14975 
14976   rst = OK;
14977 
14978   switch (scan.scantype)
14979     {
14980     case ST_NORMAL:
14981       /*a184 */
14982       myscancfg->coord.left += scan.ser;
14983       myscancfg->coord.width &= 0xffff;
14984       break;
14985     case ST_TA:
14986     case ST_NEG:
14987       myscancfg->coord.left += scan.ser;
14988       break;
14989     }
14990 
14991   /*a11b */
14992   if ((myscancfg->coord.width & 1) != 0)
14993     myscancfg->coord.width++;
14994 
14995   myscancfg->coord.top = 100;
14996   myscancfg->coord.height = 30;
14997 
14998   bytes_per_line = myscancfg->coord.width * 3;
14999 
15000   /*a1e8 */
15001   myscancfg->v157c = bytes_per_line;
15002   myscancfg->bytesperline = bytes_per_line;
15003 
15004   scanbuffer =
15005     (SANE_Byte *) malloc (((myscancfg->coord.height + 16) * bytes_per_line) *
15006 			  sizeof (SANE_Byte));
15007   if (scanbuffer == NULL)
15008     return ERROR;
15009 
15010   /* Scan image */
15011   myCalib->shading_enabled = FALSE;
15012   /*Head_Relocate(dev, dev->motorcfg->highspeedmotormove, MTR_FORWARD, 5500); */
15013 
15014   for (a = 0; a < 10; a++)
15015     {
15016       for (C = CL_RED; C <= CL_BLUE; C++)
15017 	{
15018 	  myCalibTable.pag[C] = 3;
15019 	  myCalibTable.vgag1[C] = 4;
15020 	  myCalibTable.vgag2[C] = 4;
15021 	  myCalibTable.edcg1[C] = a * 20;
15022 	}
15023 
15024       Head_Relocate (dev, dev->motorcfg->highspeedmotormove, MTR_FORWARD,
15025 		     5000);
15026       rst =
15027 	RTS_GetImage (dev, myRegs, myscancfg, &myCalibTable, scanbuffer,
15028 		      myCalib, 0x20000000, gainmode);
15029       Head_ParkHome (dev, TRUE, dev->motorcfg->parkhomemotormove);
15030 
15031       if (rst != ERROR)
15032 	{
15033 	  char name[30];
15034 	  snprintf (name, 30, "calibtest-%i.tiff", a);
15035 	  dbg_tiff_save (name,
15036 			 myscancfg->coord.width,
15037 			 myscancfg->coord.height,
15038 			 myscancfg->depth,
15039 			 CM_COLOR,
15040 			 myscancfg->resolution_x,
15041 			 myscancfg->resolution_y,
15042 			 scanbuffer,
15043 			 (myscancfg->coord.height + 16) * bytes_per_line);
15044 	}
15045     }
15046 
15047   free (scanbuffer);
15048 
15049   exit (0);
15050   return OK;
15051 }
15052 
15053 static void
prueba(SANE_Byte * a)15054 prueba (SANE_Byte * a)
15055 {
15056   /* SANE_Byte p[] = {}; */
15057   /*int z = 69; */
15058 
15059   /*(a + 11) = 0x0; */
15060   /*a[1] = a[1] | 0x40; */
15061 
15062   /*memcpy(a, &p, sizeof(p)); */
15063 
15064   /*memcpy(a + 0x12, p, 10); */
15065   /*a[0x146] &= 0xdf; */
15066 
15067 }
15068 
15069 void
shadingtest1(struct st_device * dev,SANE_Byte * Regs,struct st_calibration * myCalib)15070 shadingtest1 (struct st_device *dev, SANE_Byte * Regs,
15071 	      struct st_calibration *myCalib)
15072 {
15073   USHORT *buffer;
15074   int a;
15075   int bit[2];
15076 
15077   DBG (DBG_FNC, "+ shadingtest1(*Regs, *myCalib):\n");
15078 
15079   if ((Regs == NULL) || (myCalib == NULL))
15080     return;
15081 
15082   RTS_DMA_Reset (dev);
15083 
15084   bit[0] = (Regs[0x60b] >> 6) & 1;
15085   bit[1] = (Regs[0x60b] >> 4) & 1;
15086   Regs[0x060b] &= 0xaf;
15087 
15088   Write_Byte (dev->usb_handle, 0xee0b, Regs[0x060b]);
15089 
15090   Regs[0x1cf] = 0;		/* reset config. By default black shading disabled and pixel-rate */
15091   /*Regs[0x1cf] |= 2;  shadingbase 0x2000 */
15092   Regs[0x1cf] |= 4;		/* White shading enabled */
15093   Regs[0x1cf] |= 0x20;		/* 16 bits per channel */
15094 
15095   Write_Byte (dev->usb_handle, 0xe9cf, Regs[0x01cf]);
15096 
15097   buffer = (USHORT *) malloc (sizeof (USHORT) * myCalib->shadinglength);
15098 
15099   DBG (DBG_FNC, " -> shading length = %i\n", myCalib->shadinglength);
15100 
15101   /* fill buffer */
15102   for (a = 0; a < myCalib->shadinglength; a++)
15103     buffer[a] = RTS_Debug->shd + (a * 500);
15104 
15105   for (a = 0; a < 3; a++)
15106     {
15107       RTS_DMA_Write (dev, a | 0x14, 0,
15108 		     sizeof (USHORT) * myCalib->shadinglength,
15109 		     (SANE_Byte *) buffer);
15110     }
15111 
15112   data_bitset (&Regs[0x60b], 0x40, bit[0]);	 /*-x------*/
15113   data_bitset (&Regs[0x60b], 0x10, bit[1]);	 /*---x----*/
15114 
15115   Write_Byte (dev->usb_handle, 0xee0b, Regs[0x060b]);
15116 
15117   DBG (DBG_FNC, "- shadingtest1\n");
15118 }
15119 
15120 #endif
15121 
15122 #endif /* RTS8822_CORE */
15123