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, ®) == OK)
1145 && (rst == OK))
1146 {
1147 mode = (struct st_scanmode *) malloc (sizeof (struct st_scanmode));
1148 if (mode != NULL)
1149 {
1150 memcpy (mode, ®, 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, ¶m->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, ®) == OK)
2324 && (rst == OK))
2325 {
2326 tmg = (struct st_timing *) malloc (sizeof (struct st_timing));
2327 if (tmg != NULL)
2328 {
2329 memcpy (tmg, ®, 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, ¤tpwd) == 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, ®) != 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, ®, 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