1 /* sane - Scanner Access Now Easy.
2
3 Copyright (C) 2005 Mustek.
4 Originally maintained by Mustek
5 Author:Jack Roy 2005.5.24
6
7 This file is part of the SANE package.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <https://www.gnu.org/licenses/>.
21
22 As a special exception, the authors of SANE give permission for
23 additional uses of the libraries contained in this release of SANE.
24
25 The exception is that, if you link a SANE library with other files
26 to produce an executable, this does not by itself cause the
27 resulting executable to be covered by the GNU General Public
28 License. Your use of that executable is in no way restricted on
29 account of linking the SANE library code into it.
30
31 This exception does not, however, invalidate any other reasons why
32 the executable file might be covered by the GNU General Public
33 License.
34
35 If you submit changes to SANE to the maintainers to be included in
36 a subsequent release, you agree by submitting the changes that
37 those changes may be distributed with this exception intact.
38
39 If you write modifications of your own for SANE, it is your choice
40 whether to permit this exception to apply to your modifications.
41 If you do not wish that, delete this exception notice.
42
43 This file implements a SANE backend for the Mustek BearPaw 2448 TA Pro
44 and similar USB2 scanners. */
45
46 #include <pthread.h> /* HOLD */
47 #include <stdlib.h>
48
49 /* local header files */
50 #include "mustek_usb2_asic.c"
51
52 #include "mustek_usb2_high.h"
53
54 /* ******************++ spuicall_g.h ****************************/
55
56 /*global variable HOLD: these should go to scanner structure */
57
58 /*base type*/
59 static SANE_Bool g_bOpened;
60 static SANE_Bool g_bPrepared;
61 static SANE_Bool g_isCanceled;
62 static SANE_Bool g_bSharpen;
63 static SANE_Bool g_bFirstReadImage;
64 static SANE_Bool g_isScanning;
65 static SANE_Bool g_isSelfGamma;
66
67 static SANE_Byte g_bScanBits;
68 static SANE_Byte *g_lpReadImageHead;
69
70 static unsigned short s_wOpticalYDpi[] = { 1200, 600, 300, 150, 75, 0 };
71 static unsigned short s_wOpticalXDpi[] = { 1200, 600, 300, 150, 75, 0 };
72 static unsigned short g_X;
73 static unsigned short g_Y;
74 static unsigned short g_Width;
75 static unsigned short g_Height;
76 static unsigned short g_XDpi;
77 static unsigned short g_YDpi;
78 static unsigned short g_SWWidth;
79 static unsigned short g_SWHeight;
80 static unsigned short g_wPixelDistance; /*even & odd sensor problem */
81 static unsigned short g_wLineDistance;
82 static unsigned short g_wScanLinesPerBlock;
83 static unsigned short g_wReadedLines;
84 static unsigned short g_wReadImageLines;
85 static unsigned short g_wReadyShadingLine;
86 static unsigned short g_wStartShadingLinePos;
87 static unsigned short g_wLineartThreshold;
88
89 static unsigned int g_wtheReadyLines;
90 static unsigned int g_wMaxScanLines;
91 static unsigned int g_dwScannedTotalLines;
92 static unsigned int g_dwImageBufferSize;
93 static unsigned int g_BytesPerRow;
94 static unsigned int g_SWBytesPerRow;
95 static unsigned int g_dwCalibrationSize;
96 static unsigned int g_dwBufferSize;
97
98 static unsigned int g_dwTotalTotalXferLines;
99
100 static unsigned short *g_pGammaTable;
101 static unsigned char *g_pDeviceFile;
102
103 static pthread_t g_threadid_readimage;
104
105 /*user define type*/
106 static COLORMODE g_ScanMode;
107 static TARGETIMAGE g_tiTarget;
108 static SCANTYPE g_ScanType = ST_Reflective;
109 static SCANSOURCE g_ssScanSource;
110 static PIXELFLAVOR g_PixelFlavor;
111
112 static SUGGESTSETTING g_ssSuggest;
113 static Asic g_chip;
114
115 static int g_nSecLength, g_nDarkSecLength;
116 static int g_nSecNum, g_nDarkSecNum;
117 static unsigned short g_wCalWidth;
118 static unsigned short g_wDarkCalWidth;
119 static int g_nPowerNum;
120 static unsigned short g_wStartPosition;
121
122 static pthread_mutex_t g_scannedLinesMutex = PTHREAD_MUTEX_INITIALIZER;
123 static pthread_mutex_t g_readyLinesMutex = PTHREAD_MUTEX_INITIALIZER;
124
125 /*for modify the last point*/
126 static SANE_Byte * g_lpBefLineImageData = NULL;
127 static SANE_Bool g_bIsFirstReadBefData = TRUE;
128 static unsigned int g_dwAlreadyGetLines = 0;
129
130 /* forward declarations */
131 static SANE_Bool MustScanner_Init (void);
132 static SANE_Bool MustScanner_GetScannerState (void);
133 static SANE_Bool MustScanner_PowerControl (SANE_Bool isLampOn, SANE_Bool isTALampOn);
134 static SANE_Bool MustScanner_BackHome (void);
135 static SANE_Bool MustScanner_Prepare (SANE_Byte bScanSource);
136 #ifdef SANE_UNUSED
137 static SANE_Bool MustScanner_AdjustOffset (int nTimes, SANE_Bool * bDirection, SANE_Byte * bOffset,
138 SANE_Byte * bLastMin, SANE_Byte * bLastOffset,
139 unsigned short * wMinValue, SANE_Byte * bOffsetUpperBound,
140 SANE_Byte * bOffsetLowerBound, unsigned short wStdMinLevel,
141 unsigned short wStdMaxLevel);
142 static SANE_Bool MustScanner_SecondAdjustOffset (int nTimes, SANE_Bool * bDirection,
143 SANE_Byte * bOffset, SANE_Byte * bLastMin,
144 SANE_Byte * bLastOffset, unsigned short * wMinValue,
145 SANE_Byte * bOffsetUpperBound,
146 SANE_Byte * bOffsetLowerBound,
147 unsigned short wStdMinLevel, unsigned short wStdMaxLevel);
148 #endif
149 static unsigned short MustScanner_FiltLower (unsigned short * pSort, unsigned short TotalCount, unsigned short LowCount,
150 unsigned short HighCount);
151 static SANE_Bool MustScanner_GetRgb48BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
152 unsigned short * wLinesCount);
153 static SANE_Bool MustScanner_GetRgb48BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
154 unsigned short * wLinesCount);
155 static SANE_Bool MustScanner_GetRgb24BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
156 unsigned short * wLinesCount);
157 static SANE_Bool MustScanner_GetRgb24BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
158 unsigned short * wLinesCount);
159 static SANE_Bool MustScanner_GetMono16BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
160 unsigned short * wLinesCount);
161 static SANE_Bool MustScanner_GetMono16BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
162 unsigned short * wLinesCount);
163 static SANE_Bool MustScanner_GetMono8BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
164 unsigned short * wLinesCount);
165 static SANE_Bool MustScanner_GetMono8BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
166 unsigned short * wLinesCount);
167 static SANE_Bool MustScanner_GetMono1BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
168 unsigned short * wLinesCount);
169 static SANE_Bool MustScanner_GetMono1BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
170 unsigned short * wLinesCount);
171 static void *MustScanner_ReadDataFromScanner (void * dummy);
172 static void MustScanner_PrepareCalculateMaxMin (unsigned short wResolution);
173 static void MustScanner_CalculateMaxMin (SANE_Byte * pBuffer, unsigned short * lpMaxValue,
174 unsigned short * lpMinValue, unsigned short wResolution);
175
176 static SANE_Byte QBET4 (SANE_Byte A, SANE_Byte B);
177 static unsigned int GetScannedLines (void);
178 static unsigned int GetReadyLines (void);
179 static void AddScannedLines (unsigned short wAddLines);
180 static void AddReadyLines (void);
181 static void ModifyLinePoint (SANE_Byte * lpImageData,
182 SANE_Byte * lpImageDataBefore,
183 unsigned int dwBytesPerLine,
184 unsigned int dwLinesCount,
185 unsigned short wPixDistance, unsigned short wModPtCount);
186
187 #include "mustek_usb2_reflective.c"
188 #include "mustek_usb2_transparent.c"
189
190 /**********************************************************************
191 Author: Jack Date: 2005/05/13
192 Routine Description:
193 Parameters:
194 none
195 Return value:
196 if initialize the scanner success
197 return TRUE
198 else
199 return FALSE
200 ***********************************************************************/
201 static SANE_Bool
MustScanner_Init()202 MustScanner_Init ()
203 {
204 DBG (DBG_FUNC, "MustScanner_Init: Call in\n");
205
206 g_chip.firmwarestate = FS_NULL;
207 if (SANE_STATUS_GOOD != Asic_Open (&g_chip, g_pDeviceFile))
208 {
209 DBG (DBG_FUNC, "MustScanner_Init: Asic_Open return error\n");
210 return FALSE;
211 }
212
213 if (SANE_STATUS_GOOD != Asic_Initialize (&g_chip))
214 {
215 DBG (DBG_FUNC, "MustScanner_Init: Asic_Initialize return error\n");
216 return FALSE;
217 }
218
219 g_dwImageBufferSize = 24L * 1024L * 1024L;
220 g_dwBufferSize = 64L * 1024L;
221 g_dwCalibrationSize = 64L * 1024L;
222 g_lpReadImageHead = NULL;
223
224 g_isCanceled = FALSE;
225 g_bFirstReadImage = TRUE;
226 g_bOpened = FALSE;
227 g_bPrepared = FALSE;
228 g_bSharpen = FALSE;
229
230 g_isScanning = FALSE;
231 g_isSelfGamma = FALSE;
232 g_pGammaTable = NULL;
233
234 if (NULL != g_pDeviceFile)
235 {
236 free (g_pDeviceFile);
237 g_pDeviceFile = NULL;
238 }
239
240 g_ssScanSource = SS_Reflective;
241 g_PixelFlavor = PF_BlackIs0;
242
243 Asic_Close (&g_chip);
244
245 DBG (DBG_FUNC, "MustScanner_Init: leave MustScanner_Init\n");
246
247 return TRUE;
248 }
249
250 /**********************************************************************
251 Author: Jack Date: 2005/05/13
252 Routine Description:
253 check the scanner connect status
254 Parameters:
255 none
256 Return value:
257 if scanner's status is OK
258 return TRUE
259 else
260 return FASLE
261 ***********************************************************************/
262 static SANE_Bool
MustScanner_GetScannerState()263 MustScanner_GetScannerState ()
264 {
265
266 if (SANE_STATUS_GOOD != Asic_Open (&g_chip, g_pDeviceFile))
267 {
268 DBG (DBG_FUNC, "MustScanner_GetScannerState: Asic_Open return error\n");
269 return FALSE;
270 }
271 else
272 {
273 Asic_Close (&g_chip);
274 return TRUE;
275 }
276 }
277
278 /**********************************************************************
279 Author: Jack Date: 2005/05/13
280 Routine Description:
281 Turn the lamp on or off
282 Parameters:
283 isLampOn: turn the lamp on or off
284 isTALampOn: turn the TA lamp on or off
285 Return value:
286 if operation success
287 return TRUE
288 else
289 return FALSE
290 ***********************************************************************/
291 static SANE_Bool
MustScanner_PowerControl(SANE_Bool isLampOn,SANE_Bool isTALampOn)292 MustScanner_PowerControl (SANE_Bool isLampOn, SANE_Bool isTALampOn)
293 {
294 SANE_Bool hasTA;
295 DBG (DBG_FUNC, "MustScanner_PowerControl: Call in\n");
296 if (SANE_STATUS_GOOD != Asic_Open (&g_chip, g_pDeviceFile))
297 {
298 DBG (DBG_FUNC, "MustScanner_PowerControl: Asic_Open return error\n");
299 return FALSE;
300 }
301
302 if (SANE_STATUS_GOOD != Asic_TurnLamp (&g_chip, isLampOn))
303 {
304 DBG (DBG_FUNC,
305 "MustScanner_PowerControl: Asic_TurnLamp return error\n");
306 return FALSE;
307 }
308
309 if (SANE_STATUS_GOOD != Asic_IsTAConnected (&g_chip, &hasTA))
310 {
311 DBG (DBG_FUNC,
312 "MustScanner_PowerControl: Asic_IsTAConnected return error\n");
313 return FALSE;
314 }
315
316 if (hasTA)
317 {
318 if (SANE_STATUS_GOOD != Asic_TurnTA (&g_chip, isTALampOn))
319 {
320 DBG (DBG_FUNC,
321 "MustScanner_PowerControl: Asic_TurnTA return error\n");
322 return FALSE;
323 }
324 }
325
326 Asic_Close (&g_chip);
327
328 DBG (DBG_FUNC,
329 "MustScanner_PowerControl: leave MustScanner_PowerControl\n");
330 return TRUE;
331 }
332
333 /**********************************************************************
334 Author: Jack Date: 2005/05/13
335 Routine Description:
336 Turn the carriage home
337 Parameters:
338 none
339 Return value:
340 if the operation success
341 return TRUE
342 else
343 return FALSE
344 ***********************************************************************/
345 static SANE_Bool
MustScanner_BackHome()346 MustScanner_BackHome ()
347 {
348 DBG (DBG_FUNC, "MustScanner_BackHome: call in \n");
349
350 if (SANE_STATUS_GOOD != Asic_Open (&g_chip, g_pDeviceFile))
351 {
352 DBG (DBG_FUNC, "MustScanner_BackHome: Asic_Open return error\n");
353 return FALSE;
354 }
355
356 if (SANE_STATUS_GOOD != Asic_CarriageHome (&g_chip, FALSE))
357 {
358 DBG (DBG_FUNC,
359 "MustScanner_BackHome: Asic_CarriageHome return error\n");
360 return FALSE;
361 }
362
363 if (SANE_STATUS_GOOD != Asic_WaitUnitReady (&g_chip))
364 {
365 DBG (DBG_FUNC,
366 "MustScanner_BackHome: Asic_WaitUnitReady return error\n");
367 return FALSE;
368 }
369
370 Asic_Close (&g_chip);
371
372 DBG (DBG_FUNC, "MustScanner_BackHome: leave MustScanner_BackHome\n");
373 return TRUE;
374 }
375
376 /**********************************************************************
377 Author: Jack Date: 2005/05/13
378 Routine Description:
379 prepare the scan image
380 Parameters:
381 bScanSource: the scan source
382 Return value:
383 if operation is success
384 return TRUE
385 else
386 return FALSE
387 ***********************************************************************/
388 static SANE_Bool
MustScanner_Prepare(SANE_Byte bScanSource)389 MustScanner_Prepare (SANE_Byte bScanSource)
390 {
391 DBG (DBG_FUNC, "MustScanner_Prepare: call in\n");
392
393 if (SANE_STATUS_GOOD != Asic_Open (&g_chip, g_pDeviceFile))
394
395
396 {
397 DBG (DBG_FUNC, "MustScanner_Prepare: Asic_Open return error\n");
398 return FALSE;
399 }
400 if (SANE_STATUS_GOOD != Asic_WaitUnitReady (&g_chip))
401 {
402 DBG (DBG_FUNC,
403 "MustScanner_Prepare: Asic_WaitUnitReady return error\n");
404 return FALSE;
405 }
406
407 if (SS_Reflective == bScanSource)
408 {
409 DBG (DBG_FUNC, "MustScanner_Prepare:ScanSource is SS_Reflective\n");
410 if (SANE_STATUS_GOOD != Asic_TurnLamp (&g_chip, TRUE))
411 {
412 DBG (DBG_FUNC, "MustScanner_Prepare: Asic_TurnLamp return error\n");
413 return FALSE;
414 }
415
416 if (SANE_STATUS_GOOD != Asic_SetSource (&g_chip, LS_REFLECTIVE))
417 {
418 DBG (DBG_FUNC,
419 "MustScanner_Prepare: Asic_SetSource return error\n");
420 return FALSE;
421 }
422 }
423 else if (SS_Positive == bScanSource)
424 {
425 DBG (DBG_FUNC, "MustScanner_Prepare:ScanSource is SS_Positive\n");
426 if (SANE_STATUS_GOOD != Asic_TurnTA (&g_chip, TRUE))
427 {
428 DBG (DBG_FUNC, "MustScanner_Prepare: Asic_TurnTA return error\n");
429 return FALSE;
430 }
431 if (SANE_STATUS_GOOD != Asic_SetSource (&g_chip, LS_POSITIVE))
432 {
433 DBG (DBG_FUNC,
434 "MustScanner_Prepare: Asic_SetSource return error\n");
435 return FALSE;
436 }
437 }
438 else if (SS_Negative == bScanSource)
439 {
440 DBG (DBG_FUNC, "MustScanner_Prepare:ScanSource is SS_Negative\n");
441
442 if (SANE_STATUS_GOOD != Asic_TurnTA (&g_chip, TRUE))
443 {
444 DBG (DBG_FUNC, "MustScanner_Prepare: Asic_TurnTA return error\n");
445 return FALSE;
446 }
447
448 if (SANE_STATUS_GOOD != Asic_SetSource (&g_chip, LS_NEGATIVE))
449 {
450 DBG (DBG_FUNC,
451 "MustScanner_Prepare: Asic_SetSource return error\n");
452 return FALSE;
453 }
454 DBG (DBG_FUNC, "MustScanner_Prepare: Asic_SetSource return good\n");
455 }
456
457 Asic_Close (&g_chip);
458 g_bPrepared = TRUE;
459
460 DBG (DBG_FUNC, "MustScanner_Prepare: leave MustScanner_Prepare\n");
461 return TRUE;
462 }
463
464 #ifdef SANE_UNUSED
465 /**********************************************************************
466 Author: Jack Date: 2005/05/15
467 Routine Description:
468 Adjuest the offset
469 Parameters:
470 nTimes: Adjuest offset the times
471 bDirection: whether direction
472 bOffset: the data of offset
473 bLastMin: the last min data
474 bLastOffset: the last offset data
475 wMinValue: the min value of offset
476 bOffsetUpperBound: the upper bound of offset
477 bOffsetLowerBound: the lower bound of offset
478 wStdMinLevel: the min level of offset
479 wStdMaxLevel: the max level of offset
480 Return value:
481 if the operation is success
482 return TRUE
483 else
484 return FALSE
485 ***********************************************************************/
486 static SANE_Bool
MustScanner_AdjustOffset(int nTimes,SANE_Bool * bDirection,SANE_Byte * bOffset,SANE_Byte * bLastMin,SANE_Byte * bLastOffset,unsigned short * wMinValue,SANE_Byte * bOffsetUpperBound,SANE_Byte * bOffsetLowerBound,unsigned short wStdMinLevel,unsigned short wStdMaxLevel)487 MustScanner_AdjustOffset (int nTimes, SANE_Bool * bDirection, SANE_Byte * bOffset,
488 SANE_Byte * bLastMin, SANE_Byte * bLastOffset,
489 unsigned short * wMinValue, SANE_Byte * bOffsetUpperBound,
490 SANE_Byte * bOffsetLowerBound, unsigned short wStdMinLevel,
491 unsigned short wStdMaxLevel)
492 {
493 if ((*wMinValue <= wStdMaxLevel) && (*wMinValue >= wStdMinLevel))
494 {
495 return TRUE;
496 }
497
498 if (nTimes == 0)
499 {
500 *bLastMin = LOSANE_Byte (*wMinValue);
501 *bLastOffset = *bOffset;
502
503 if (*wMinValue == 255)
504 {
505 *bOffset = 0;
506 }
507 else
508 {
509 *bOffset = 255;
510 }
511 }
512
513 if (nTimes == 1)
514 {
515 if (*wMinValue > *bLastMin)
516 {
517 if (*wMinValue > wStdMaxLevel && *bLastMin > wStdMaxLevel)
518 {
519 *bDirection = !(*bDirection);
520 return TRUE;
521 }
522
523 if (*wMinValue < wStdMinLevel && *bLastMin < wStdMinLevel)
524 return TRUE;
525 }
526
527 if (*wMinValue < *bLastMin)
528 {
529 if (*wMinValue < wStdMinLevel && *bLastMin < wStdMinLevel)
530 *bDirection = !(*bDirection);
531
532 if (*wMinValue > wStdMaxLevel && *bLastMin > wStdMaxLevel)
533 return TRUE;
534 }
535 }
536
537 if (nTimes > 1)
538 {
539 if (*wMinValue > *bLastMin)
540 {
541 SANE_Byte bTemp;
542
543 bTemp = *bOffset;
544
545 *bOffset = (*bOffsetUpperBound + *bOffsetLowerBound) / 2;
546
547 if (nTimes > 2)
548 {
549 if (*wMinValue > wStdMaxLevel)
550 if (bDirection)
551 *bOffsetLowerBound = bTemp;
552 else
553 *bOffsetUpperBound = bTemp;
554
555
556 else if (bDirection)
557 *bOffsetUpperBound = bTemp;
558 else
559 *bOffsetLowerBound = bTemp;
560 }
561
562 *bLastOffset = bTemp;
563 *bLastMin = (SANE_Byte) * wMinValue;
564 }
565 else
566 {
567 SANE_Byte bTemp;
568
569 bTemp = *bOffset;
570
571 *bOffset = (*bOffsetUpperBound + *bOffsetLowerBound) / 2;
572
573 if (nTimes > 2)
574 {
575 if (*wMinValue == *bLastMin)
576 {
577 if (*wMinValue > wStdMaxLevel)
578 {
579 if (!bDirection)
580 *bOffsetUpperBound = bTemp;
581 else
582 *bOffsetLowerBound = bTemp;
583 }
584 else
585 {
586 if (!bDirection)
587 *bOffsetLowerBound = bTemp;
588 else
589 *bOffsetUpperBound = bTemp;
590 }
591 }
592 else
593 {
594 if (*wMinValue > wStdMaxLevel)
595 {
596 if (bDirection)
597 *bOffsetUpperBound = bTemp;
598 else
599 *bOffsetLowerBound = bTemp;
600 }
601 else
602 {
603 if (bDirection)
604 *bOffsetLowerBound = bTemp;
605 else
606 *bOffsetUpperBound = bTemp;
607 }
608 }
609 }
610
611 *bLastOffset = bTemp;
612 *bLastMin = (SANE_Byte) * wMinValue;
613
614 }
615 } /* end of if(nTimes > 1) */
616
617 return TRUE;
618 }
619 #endif
620
621 #ifdef SANE_UNUSED
622 /**********************************************************************
623
624 Author: Jack Date: 2005/05/15
625 Routine Description:
626 Adjuest the offset second times
627 Parameters:
628 nTimes: Adjuest offset the times
629 bDirection: whether direction
630 bOffset: the data of offset
631 bLastMin: the last min data
632 bLastOffset: the last offset data
633 wMinValue: the min value of offset
634 bOffsetUpperBound: the upper bound of offset
635 bOffsetLowerBound: the lower bound of offset
636 wStdMinLevel: the min level of offset
637 wStdMaxLevel: the max level of offset
638 Return value:
639 if the operation is success
640 return TRUE
641 else
642 return FALSE
643 ***********************************************************************/
644 static SANE_Bool
MustScanner_SecondAdjustOffset(int nTimes,SANE_Bool * bDirection,SANE_Byte * bOffset,SANE_Byte * bLastMin,SANE_Byte * bLastOffset,unsigned short * wMinValue,SANE_Byte * bOffsetUpperBound,SANE_Byte * bOffsetLowerBound,unsigned short wStdMinLevel,unsigned short wStdMaxLevel)645 MustScanner_SecondAdjustOffset (int nTimes, SANE_Bool * bDirection, SANE_Byte * bOffset,
646 SANE_Byte * bLastMin, SANE_Byte * bLastOffset,
647 unsigned short * wMinValue, SANE_Byte * bOffsetUpperBound,
648 SANE_Byte * bOffsetLowerBound, unsigned short wStdMinLevel,
649 unsigned short wStdMaxLevel)
650 {
651 if ((*wMinValue <= wStdMaxLevel) && (*wMinValue >= wStdMinLevel))
652 {
653 return TRUE;
654 }
655 if (nTimes == 0)
656 {
657 *bLastMin = LOSANE_Byte (*wMinValue);
658 *bLastOffset = *bOffset;
659
660 if (*bDirection == 0)
661 {
662 *bOffsetUpperBound = *bLastOffset;
663 *bOffsetLowerBound = 0;
664 *bOffset = 0;
665 }
666 else
667 {
668 *bOffsetUpperBound = 255;
669 *bOffsetLowerBound = *bLastOffset;
670 *bOffset = 255;
671 }
672 }
673
674 if (nTimes >= 1)
675 {
676 if (*wMinValue > wStdMaxLevel)
677 {
678 if (*wMinValue > *bLastMin)
679 {
680 if (*bDirection == 0)
681 {
682 *bOffsetUpperBound = *bOffset;
683 }
684 else
685 {
686 *bOffsetLowerBound = *bOffset;
687 }
688
689 *bOffset = (*bOffsetUpperBound + *bOffsetLowerBound) / 2;
690 }
691 else
692 {
693 if (*bDirection == 1)
694 {
695 *bOffsetUpperBound = *bOffset;
696 *bOffset = (*bOffsetUpperBound + *bOffsetLowerBound) / 2;
697 }
698 else
699 {
700 *bOffsetLowerBound = *bOffset;
701 *bOffset = (*bOffsetUpperBound + *bOffsetLowerBound) / 2;
702 }
703 }
704 } /*end of if(*wMinValue > MAX_OFFSET) */
705
706
707 if (*wMinValue < wStdMinLevel)
708 {
709 if (*wMinValue > *bLastMin)
710 {
711 if (*bDirection == 0)
712 {
713 *bOffsetLowerBound = *bOffset;
714 }
715 else
716 {
717 *bOffsetUpperBound = *bOffset;
718 }
719
720 *bOffset = (*bOffsetUpperBound + *bOffsetLowerBound) / 2;
721 }
722 else
723 {
724 if (*bDirection == 1)
725 {
726 *bOffsetUpperBound = *bOffset;
727 *bOffset = (*bOffsetUpperBound + *bOffsetLowerBound) / 2;
728 }
729 else
730 {
731 *bOffsetLowerBound = *bOffset;
732 *bOffset = (*bOffsetUpperBound + *bOffsetLowerBound) / 2;
733 }
734 }
735 } /*end of if(*wMinValue > MIN_OFFSET) */
736 *bLastMin = (SANE_Byte) * wMinValue;
737 } /*end of if(nTimes >= 1) */
738
739 /* HOLD: missing return value! Correct? */
740 return FALSE;
741 }
742 #endif
743
744 /**********************************************************************
745 Author: Jack Date: 2005/05/15
746 Routine Description:
747 Filter the data
748 Parameters:
749 pSort: the sort data
750 TotalCount: the total count
751 LowCount: the low count
752 HighCount: the upper count
753 Return value:
754 the data of Filter
755 ***********************************************************************/
756 static unsigned short
MustScanner_FiltLower(unsigned short * pSort,unsigned short TotalCount,unsigned short LowCount,unsigned short HighCount)757 MustScanner_FiltLower (unsigned short * pSort, unsigned short TotalCount, unsigned short LowCount,
758 unsigned short HighCount)
759 {
760 unsigned short Bound = TotalCount - 1;
761 unsigned short LeftCount = HighCount - LowCount;
762 int Temp = 0;
763 unsigned int Sum = 0;
764 unsigned short i, j;
765
766 for (i = 0; i < Bound; i++)
767
768 {
769 for (j = 0; j < Bound - i; j++)
770 {
771 if (pSort[j + 1] > pSort[j])
772 {
773 Temp = pSort[j];
774 pSort[j] = pSort[j + 1];
775 pSort[j + 1] = Temp;
776 }
777 }
778 }
779
780 for (i = 0; i < LeftCount; i++)
781 Sum += pSort[i + LowCount];
782 return (unsigned short) (Sum / LeftCount);
783 }
784
785 /**********************************************************************
786 Author: Jack Date: 2005/05/15
787 Routine Description:
788 Repair line when single CCD and color is 48bit
789 Parameters:
790 lpLine: point to image be repaired
791 isOrderInvert: RGB or BGR
792 wLinesCount: how many line be repaired
793 Return value:
794 if the operation is success
795 return TRUE
796 else
797 return FALSE
798 ***********************************************************************/
799 static SANE_Bool
MustScanner_GetRgb48BitLine(SANE_Byte * lpLine,SANE_Bool isOrderInvert,unsigned short * wLinesCount)800 MustScanner_GetRgb48BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
801 unsigned short * wLinesCount)
802 {
803 unsigned short wWantedTotalLines;
804 unsigned short TotalXferLines;
805 unsigned short wRLinePos = 0;
806 unsigned short wGLinePos = 0;
807 unsigned short wBLinePos = 0;
808 unsigned short wRTempData;
809 unsigned short wGTempData;
810 unsigned short wBTempData;
811 unsigned short i;
812
813 DBG (DBG_FUNC, "MustScanner_GetRgb48BitLine: call in \n");
814
815 g_isCanceled = FALSE;
816 g_isScanning = TRUE;
817 wWantedTotalLines = *wLinesCount;
818 TotalXferLines = 0;
819
820 if (g_bFirstReadImage)
821 {
822 pthread_create (&g_threadid_readimage, NULL,
823 MustScanner_ReadDataFromScanner, NULL);
824 DBG (DBG_FUNC, "MustScanner_GetRgb48BitLine: thread create\n");
825 g_bFirstReadImage = FALSE;
826 }
827
828 if (!isOrderInvert)
829 {
830 for (; TotalXferLines < wWantedTotalLines;)
831 {
832 if (g_dwTotalTotalXferLines >= g_SWHeight)
833 {
834 pthread_cancel (g_threadid_readimage);
835 pthread_join (g_threadid_readimage, NULL);
836 DBG (DBG_FUNC, "MustScanner_GetRgb48BitLine: thread exit\n");
837
838 *wLinesCount = TotalXferLines;
839 g_isScanning = FALSE;
840 return TRUE;
841 }
842
843 if (GetScannedLines () > g_wtheReadyLines)
844 {
845 wRLinePos = g_wtheReadyLines % g_wMaxScanLines;
846 wGLinePos =
847 (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
848 wBLinePos =
849 (g_wtheReadyLines - g_wLineDistance * 2) % g_wMaxScanLines;
850
851 for (i = 0; i < g_SWWidth; i++)
852 {
853 wRTempData =
854 *(g_lpReadImageHead + wRLinePos * g_BytesPerRow + i * 6 +
855 0);
856 wRTempData +=
857 *(g_lpReadImageHead + wRLinePos * g_BytesPerRow + i * 6 +
858 1) << 8;
859 wGTempData =
860 *(g_lpReadImageHead + wGLinePos * g_BytesPerRow + i * 6 +
861 2);
862 wGTempData +=
863 *(g_lpReadImageHead + wGLinePos * g_BytesPerRow + i * 6 +
864 3) << 8;
865 wBTempData =
866 *(g_lpReadImageHead + wBLinePos * g_BytesPerRow + i * 6 +
867 4);
868 wBTempData +=
869 *(g_lpReadImageHead + wBLinePos * g_BytesPerRow + i * 6 +
870 5) << 8;
871 *(lpLine + i * 6 + 0) = LOBYTE (g_pGammaTable[wRTempData]);
872 *(lpLine + i * 6 + 1) = HIBYTE (g_pGammaTable[wRTempData]);
873 *(lpLine + i * 6 + 2) =
874 LOBYTE (g_pGammaTable[wGTempData + 65536]);
875 *(lpLine + i * 6 + 3) =
876 HIBYTE (g_pGammaTable[wGTempData + 65536]);
877 *(lpLine + i * 6 + 4) =
878 LOBYTE (g_pGammaTable[wBTempData + 131072]);
879 *(lpLine + i * 6 + 5) =
880 HIBYTE (g_pGammaTable[wBTempData + 131072]);
881 }
882 TotalXferLines++;
883 g_dwTotalTotalXferLines++;
884 lpLine += g_SWBytesPerRow;
885 AddReadyLines ();
886 }
887
888 if (g_isCanceled)
889 {
890 pthread_cancel (g_threadid_readimage);
891 pthread_join (g_threadid_readimage, NULL);
892
893 DBG (DBG_FUNC, "MustScanner_GetRgb48BitLine: thread exit\n");
894
895 break;
896 }
897 }
898 }
899 else
900 {
901 for (; TotalXferLines < wWantedTotalLines;)
902 {
903 if (g_dwTotalTotalXferLines >= g_SWHeight)
904 {
905 pthread_cancel (g_threadid_readimage);
906 pthread_join (g_threadid_readimage, NULL);
907
908 DBG (DBG_FUNC, "MustScanner_GetRgb48BitLine: thread exit\n");
909
910
911 *wLinesCount = TotalXferLines;
912 g_isScanning = FALSE;
913 return TRUE;
914 }
915
916 if (GetScannedLines () > g_wtheReadyLines)
917 {
918 wRLinePos = g_wtheReadyLines % g_wMaxScanLines;
919 wGLinePos =
920 (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
921 wBLinePos =
922 (g_wtheReadyLines - g_wLineDistance * 2) % g_wMaxScanLines;
923
924 for (i = 0; i < g_SWWidth; i++)
925 {
926 wRTempData =
927 *(g_lpReadImageHead + wRLinePos * g_BytesPerRow + i * 6 +
928 0);
929 wRTempData +=
930 *(g_lpReadImageHead + wRLinePos * g_BytesPerRow + i * 6 +
931 1) << 8;
932 wGTempData =
933 *(g_lpReadImageHead + wGLinePos * g_BytesPerRow + i * 6 +
934 2);
935 wGTempData +=
936 *(g_lpReadImageHead + wGLinePos * g_BytesPerRow + i * 6 +
937 3) << 8;
938 wBTempData =
939 *(g_lpReadImageHead + wBLinePos * g_BytesPerRow + i * 6 +
940 4);
941 wBTempData +=
942 *(g_lpReadImageHead + wBLinePos * g_BytesPerRow + i * 6 +
943 5) << 8;
944 *(lpLine + i * 6 + 4) = LOBYTE (g_pGammaTable[wRTempData]);
945 *(lpLine + i * 6 + 5) = HIBYTE (g_pGammaTable[wRTempData]);
946 *(lpLine + i * 6 + 2) =
947 LOBYTE (g_pGammaTable[wGTempData + 65536]);
948 *(lpLine + i * 6 + 3) =
949 HIBYTE (g_pGammaTable[wGTempData + 65536]);
950 *(lpLine + i * 6 + 0) =
951 LOBYTE (g_pGammaTable[wBTempData + 131072]);
952 *(lpLine + i * 6 + 1) =
953 HIBYTE (g_pGammaTable[wBTempData + 131072]);
954 }
955
956 TotalXferLines++;
957 g_dwTotalTotalXferLines++;
958 lpLine += g_SWBytesPerRow;
959 AddReadyLines ();
960
961 }
962 if (g_isCanceled)
963 {
964 pthread_cancel (g_threadid_readimage);
965 pthread_join (g_threadid_readimage, NULL);
966
967 DBG (DBG_FUNC, "MustScanner_GetRgb48BitLine: thread exit\n");
968 break;
969 }
970 } /*end for */
971 }
972
973 *wLinesCount = TotalXferLines;
974 g_isScanning = FALSE;
975
976 DBG (DBG_FUNC,
977 "MustScanner_GetRgb48BitLine: leave MustScanner_GetRgb48BitLine\n");
978 return TRUE;
979 }
980
981 /**********************************************************************
982 Author: Jack Date: 2005/05/15
983 Routine Description:
984 Repair line when double CCD and color is 48bit
985 Parameters:
986 lpLine: point to image be repaired
987 isOrderInvert: RGB or BGR
988 wLinesCount: how many line be repaired
989 Return value:
990 if the operation is success
991 return TRUE
992 else
993 return FALSE
994 ***********************************************************************/
995 static SANE_Bool
MustScanner_GetRgb48BitLine1200DPI(SANE_Byte * lpLine,SANE_Bool isOrderInvert,unsigned short * wLinesCount)996 MustScanner_GetRgb48BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
997 unsigned short * wLinesCount)
998 {
999 unsigned short wWantedTotalLines;
1000 unsigned short TotalXferLines;
1001
1002 unsigned short wRLinePosOdd = 0;
1003 unsigned short wGLinePosOdd = 0;
1004 unsigned short wBLinePosOdd = 0;
1005 unsigned short wRLinePosEven = 0;
1006 unsigned short wGLinePosEven = 0;
1007 unsigned short wBLinePosEven = 0;
1008 unsigned int wRTempData;
1009 unsigned int wGTempData;
1010 unsigned int wBTempData;
1011 unsigned int wNextTempData;
1012 unsigned short i;
1013
1014 DBG (DBG_FUNC, "MustScanner_GetRgb48BitLine1200DPI: call in \n");
1015
1016 TotalXferLines = 0;
1017 wWantedTotalLines = *wLinesCount;
1018
1019 g_isCanceled = FALSE;
1020 g_isScanning = TRUE;
1021
1022 if (g_bFirstReadImage)
1023 {
1024 pthread_create (&g_threadid_readimage, NULL,
1025 MustScanner_ReadDataFromScanner, NULL);
1026 DBG (DBG_FUNC, "MustScanner_GetRgb48BitLine1200DPI: thread create\n");
1027 g_bFirstReadImage = FALSE;
1028 }
1029
1030 if (!isOrderInvert)
1031 {
1032 for (; TotalXferLines < wWantedTotalLines;)
1033 {
1034 if (g_dwTotalTotalXferLines >= g_SWHeight)
1035 {
1036 pthread_cancel (g_threadid_readimage);
1037 pthread_join (g_threadid_readimage, NULL);
1038 DBG (DBG_FUNC,
1039 "MustScanner_GetRgb48BitLine1200DPI: thread exit\n");
1040
1041 *wLinesCount = TotalXferLines;
1042 g_isScanning = FALSE;
1043 return TRUE;
1044 }
1045
1046 if (GetScannedLines () > g_wtheReadyLines)
1047 {
1048 if (ST_Reflective == g_ScanType)
1049 {
1050 wRLinePosOdd =
1051 (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
1052 wGLinePosOdd =
1053 (g_wtheReadyLines - g_wLineDistance -
1054 g_wPixelDistance) % g_wMaxScanLines;
1055 wBLinePosOdd =
1056 (g_wtheReadyLines - g_wLineDistance * 2 -
1057 g_wPixelDistance) % g_wMaxScanLines;
1058 wRLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
1059 wGLinePosEven =
1060 (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
1061 wBLinePosEven =
1062 (g_wtheReadyLines -
1063 g_wLineDistance * 2) % g_wMaxScanLines;
1064 }
1065 else
1066 {
1067 wRLinePosEven =
1068 (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
1069 wGLinePosEven =
1070 (g_wtheReadyLines - g_wLineDistance -
1071 g_wPixelDistance) % g_wMaxScanLines;
1072 wBLinePosEven =
1073 (g_wtheReadyLines - g_wLineDistance * 2 -
1074 g_wPixelDistance) % g_wMaxScanLines;
1075 wRLinePosOdd = (g_wtheReadyLines) % g_wMaxScanLines;
1076 wGLinePosOdd =
1077 (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
1078 wBLinePosOdd =
1079 (g_wtheReadyLines -
1080 g_wLineDistance * 2) % g_wMaxScanLines;
1081 }
1082
1083 for (i = 0; i < g_SWWidth;)
1084 {
1085 if (i + 1 != g_SWWidth)
1086 {
1087 wRTempData =
1088 *(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
1089 i * 6 + 0);
1090 wRTempData +=
1091 *(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
1092 i * 6 + 1) << 8;
1093 wNextTempData =
1094 *(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
1095 (i + 1) * 6 + 0);
1096 wNextTempData +=
1097 *(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
1098 (i + 1) * 6 + 1) << 8;
1099 wRTempData = (wRTempData + wNextTempData) >> 1;
1100
1101 wGTempData =
1102 *(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
1103 i * 6 + 2);
1104 wGTempData +=
1105 *(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
1106 i * 6 + 3) << 8;
1107 wNextTempData =
1108 *(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
1109 (i + 1) * 6 + 2);
1110 wNextTempData +=
1111 *(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
1112 (i + 1) * 6 + 3) << 8;
1113 wGTempData = (wGTempData + wNextTempData) >> 1;
1114
1115 wBTempData =
1116 *(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
1117 i * 6 + 4);
1118 wBTempData +=
1119 *(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
1120 i * 6 + 5) << 8;
1121 wNextTempData =
1122 *(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
1123 (i + 1) * 6 + 4);
1124 wNextTempData +=
1125 *(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
1126 (i + 1) * 6 + 5) << 8;
1127 wBTempData = (wBTempData + wNextTempData) >> 1;
1128
1129 *(lpLine + i * 6 + 0) =
1130 LOBYTE (g_pGammaTable[wRTempData]);
1131 *(lpLine + i * 6 + 1) =
1132 HIBYTE (g_pGammaTable[wRTempData]);
1133 *(lpLine + i * 6 + 2) =
1134 LOBYTE (g_pGammaTable[wGTempData + 65536]);
1135 *(lpLine + i * 6 + 3) =
1136 HIBYTE (g_pGammaTable[wGTempData + 65536]);
1137 *(lpLine + i * 6 + 4) =
1138 LOBYTE (g_pGammaTable[wBTempData + 131072]);
1139 *(lpLine + i * 6 + 5) =
1140 HIBYTE (g_pGammaTable[wBTempData + 131072]);
1141 i++;
1142 if (i >= g_SWWidth)
1143 {
1144 break;
1145 }
1146
1147 wRTempData =
1148 *(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
1149 i * 6 + 0);
1150 wRTempData +=
1151 *(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
1152 i * 6 + 1) << 8;
1153 wNextTempData =
1154 *(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
1155 (i + 1) * 6 + 0);
1156 wNextTempData +=
1157 *(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
1158 (i + 1) * 6 + 1) << 8;
1159 wRTempData = (wRTempData + wNextTempData) >> 1;
1160
1161 wGTempData =
1162 *(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
1163 i * 6 + 2);
1164 wGTempData +=
1165 *(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
1166 i * 6 + 3) << 8;
1167 wNextTempData =
1168 *(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
1169 (i + 1) * 6 + 2);
1170 wNextTempData +=
1171 *(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
1172 (i + 1) * 6 + 3) << 8;
1173 wGTempData = (wGTempData + wNextTempData) >> 1;
1174
1175 wBTempData =
1176 *(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
1177 i * 6 + 4);
1178 wBTempData +=
1179 *(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
1180 i * 6 + 5) << 8;
1181 wNextTempData =
1182 *(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
1183 (i + 1) * 6 + 4);
1184 wNextTempData +=
1185 *(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
1186 (i + 1) * 6 + 5) << 8;
1187 wBTempData = (wBTempData + wNextTempData) >> 1;
1188
1189 *(lpLine + i * 6 + 0) =
1190 LOBYTE (g_pGammaTable[wRTempData]);
1191 *(lpLine + i * 6 + 1) =
1192 HIBYTE (g_pGammaTable[wRTempData]);
1193 *(lpLine + i * 6 + 2) =
1194 LOBYTE (g_pGammaTable[wGTempData + 65536]);
1195 *(lpLine + i * 6 + 3) =
1196 HIBYTE (g_pGammaTable[wGTempData + 65536]);
1197 *(lpLine + i * 6 + 4) =
1198 LOBYTE (g_pGammaTable[wBTempData + 131072]);
1199 *(lpLine + i * 6 + 5) =
1200 HIBYTE (g_pGammaTable[wBTempData + 131072]);
1201
1202 i++;
1203 }
1204 }
1205
1206 TotalXferLines++;
1207 g_dwTotalTotalXferLines++;
1208 lpLine += g_SWBytesPerRow;
1209 AddReadyLines ();
1210 }
1211 if (g_isCanceled)
1212 {
1213 pthread_cancel (g_threadid_readimage);
1214 pthread_join (g_threadid_readimage, NULL);
1215 DBG (DBG_FUNC,
1216 "MustScanner_GetRgb48BitLine1200DPI: thread exit\n");
1217 break;
1218
1219 }
1220 }
1221
1222
1223 }
1224 else
1225 {
1226 for (; TotalXferLines < wWantedTotalLines;)
1227 {
1228 if (g_dwTotalTotalXferLines >= g_SWHeight)
1229 {
1230 pthread_cancel (g_threadid_readimage);
1231 pthread_join (g_threadid_readimage, NULL);
1232 DBG (DBG_FUNC,
1233 "MustScanner_GetRgb48BitLine1200DPI: thread exit\n");
1234
1235 *wLinesCount = TotalXferLines;
1236 g_isScanning = FALSE;
1237 return TRUE;
1238 }
1239
1240 if (GetScannedLines () > g_wtheReadyLines)
1241 {
1242 if (ST_Reflective == g_ScanType)
1243 {
1244 wRLinePosOdd =
1245 (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
1246 wGLinePosOdd =
1247 (g_wtheReadyLines - g_wLineDistance -
1248 g_wPixelDistance) % g_wMaxScanLines;
1249 wBLinePosOdd =
1250 (g_wtheReadyLines - g_wLineDistance * 2 -
1251 g_wPixelDistance) % g_wMaxScanLines;
1252 wRLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
1253 wGLinePosEven =
1254 (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
1255 wBLinePosEven =
1256 (g_wtheReadyLines -
1257 g_wLineDistance * 2) % g_wMaxScanLines;
1258 }
1259 else
1260 {
1261 wRLinePosEven =
1262 (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
1263 wGLinePosEven =
1264 (g_wtheReadyLines - g_wLineDistance -
1265 g_wPixelDistance) % g_wMaxScanLines;
1266 wBLinePosEven =
1267 (g_wtheReadyLines - g_wLineDistance * 2 -
1268 g_wPixelDistance) % g_wMaxScanLines;
1269 wRLinePosOdd = (g_wtheReadyLines) % g_wMaxScanLines;
1270 wGLinePosOdd =
1271 (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
1272 wBLinePosOdd =
1273 (g_wtheReadyLines -
1274 g_wLineDistance * 2) % g_wMaxScanLines;
1275 }
1276
1277 for (i = 0; i < g_SWWidth;)
1278 {
1279 if ((i + 1) != g_SWWidth)
1280 {
1281 wRTempData =
1282 *(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
1283 i * 6 + 0);
1284 wRTempData +=
1285 *(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
1286 i * 6 + 1) << 8;
1287 wNextTempData =
1288 *(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
1289 (i + 1) * 6 + 0);
1290 wNextTempData +=
1291 *(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
1292 (i + 1) * 6 + 1) << 8;
1293 wRTempData = (wRTempData + wNextTempData) >> 1;
1294
1295 wGTempData =
1296 *(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
1297 i * 6 + 2);
1298 wGTempData +=
1299 *(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
1300 i * 6 + 3) << 8;
1301 wNextTempData =
1302 *(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
1303 (i + 1) * 6 + 2);
1304 wNextTempData +=
1305 *(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
1306 (i + 1) * 6 + 3) << 8;
1307 wGTempData = (wGTempData + wNextTempData) >> 1;
1308
1309 wBTempData =
1310 *(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
1311 i * 6 + 4);
1312 wBTempData +=
1313 *(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
1314 i * 6 + 5) << 8;
1315 wNextTempData =
1316 *(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
1317 (i + 1) * 6 + 4);
1318 wNextTempData +=
1319 *(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
1320 (i + 1) * 6 + 5) << 8;
1321 wBTempData = (wBTempData + wNextTempData) >> 1;
1322
1323 *(lpLine + i * 6 + 4) =
1324 LOBYTE (g_pGammaTable[wRTempData]);
1325 *(lpLine + i * 6 + 5) =
1326 HIBYTE (g_pGammaTable[wRTempData]);
1327 *(lpLine + i * 6 + 2) =
1328 LOBYTE (g_pGammaTable[wGTempData + 65536]);
1329 *(lpLine + i * 6 + 3) =
1330 HIBYTE (g_pGammaTable[wGTempData + 65536]);
1331 *(lpLine + i * 6 + 0) =
1332 LOBYTE (g_pGammaTable[wBTempData + 131072]);
1333 *(lpLine + i * 6 + 1) =
1334 HIBYTE (g_pGammaTable[wBTempData + 131072]);
1335 i++;
1336 if (i >= g_SWWidth)
1337 {
1338 break;
1339 }
1340
1341 wRTempData =
1342 *(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
1343 i * 6 + 0);
1344 wRTempData +=
1345 *(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
1346 i * 6 + 1) << 8;
1347 wNextTempData =
1348 *(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
1349 (i + 1) * 6 + 0);
1350 wNextTempData +=
1351 *(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
1352 (i + 1) * 6 + 1) << 8;
1353 wRTempData = (wRTempData + wNextTempData) >> 1;
1354
1355 wGTempData =
1356 *(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
1357 i * 6 + 2);
1358 wGTempData +=
1359 *(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
1360 i * 6 + 3) << 8;
1361 wNextTempData =
1362 *(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
1363 (i + 1) * 6 + 2);
1364 wNextTempData +=
1365 *(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
1366 (i + 1) * 6 + 3) << 8;
1367 wGTempData = (wGTempData + wNextTempData) >> 1;
1368
1369
1370 wBTempData =
1371 *(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
1372 i * 6 + 4);
1373 wBTempData +=
1374 *(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
1375 i * 6 + 5) << 8;
1376 wNextTempData =
1377 *(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
1378 (i + 1) * 6 + 4);
1379 wNextTempData +=
1380 *(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
1381 (i + 1) * 6 + 5) << 8;
1382 wBTempData = (wBTempData + wNextTempData) >> 1;
1383
1384 *(lpLine + i * 6 + 4) =
1385 LOBYTE (g_pGammaTable[wRTempData]);
1386 *(lpLine + i * 6 + 5) =
1387 HIBYTE (g_pGammaTable[wRTempData]);
1388 *(lpLine + i * 6 + 2) =
1389 LOBYTE (g_pGammaTable[wGTempData + 65536]);
1390 *(lpLine + i * 6 + 3) =
1391 HIBYTE (g_pGammaTable[wGTempData + 65536]);
1392 *(lpLine + i * 6 + 0) =
1393 LOBYTE (g_pGammaTable[wBTempData + 131072]);
1394 *(lpLine + i * 6 + 1) =
1395 HIBYTE (g_pGammaTable[wBTempData + 131072]);
1396 i++;
1397 }
1398 }
1399
1400 TotalXferLines++;
1401 g_dwTotalTotalXferLines++;
1402 lpLine += g_SWBytesPerRow;
1403 AddReadyLines ();
1404 }
1405 if (g_isCanceled)
1406 {
1407 pthread_cancel (g_threadid_readimage);
1408 pthread_join (g_threadid_readimage, NULL);
1409
1410 DBG (DBG_FUNC,
1411 "MustScanner_GetRgb48BitLine1200DPI: thread exit\n");
1412
1413 break;
1414 }
1415 }
1416 }
1417
1418 *wLinesCount = TotalXferLines;
1419 g_isScanning = FALSE;
1420
1421 DBG (DBG_FUNC,
1422 "MustScanner_GetRgb48BitLine1200DPI: leave MustScanner_GetRgb48BitLine1200DPI\n");
1423 return TRUE;
1424 }
1425
1426 /**********************************************************************
1427 Author: Jack Date: 2005/05/15
1428 Routine Description:
1429 Repair line when single CCD and color is 24bit
1430 Parameters:
1431 lpLine: point to image be repaired
1432 isOrderInvert: RGB or BGR
1433 wLinesCount: how many line be repaired
1434 Return value:
1435 if the operation is success
1436 return TRUE
1437 else
1438 return FALSE
1439 ***********************************************************************/
1440 static SANE_Bool
MustScanner_GetRgb24BitLine(SANE_Byte * lpLine,SANE_Bool isOrderInvert,unsigned short * wLinesCount)1441 MustScanner_GetRgb24BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
1442 unsigned short * wLinesCount)
1443 {
1444 unsigned short wWantedTotalLines;
1445 unsigned short TotalXferLines;
1446 unsigned short wRLinePos = 0;
1447 unsigned short wGLinePos = 0;
1448 unsigned short wBLinePos = 0;
1449 SANE_Byte byRed;
1450 SANE_Byte byGreen;
1451 SANE_Byte byBlue;
1452 SANE_Byte bNextPixel = 0;
1453 unsigned short i;
1454
1455 unsigned short tempR, tempG, tempB;
1456
1457 DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: call in\n");
1458
1459 g_isCanceled = FALSE;
1460 g_isScanning = TRUE;
1461
1462 wWantedTotalLines = *wLinesCount;
1463 DBG (DBG_FUNC,
1464 "MustScanner_GetRgb24BitLine: get wWantedTotalLines= %d\n",
1465 wWantedTotalLines);
1466
1467 TotalXferLines = 0;
1468
1469 if (g_bFirstReadImage)
1470 {
1471 pthread_create (&g_threadid_readimage, NULL,
1472 MustScanner_ReadDataFromScanner, NULL);
1473 DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: thread create\n");
1474
1475 g_bFirstReadImage = FALSE;
1476 }
1477
1478 if (!isOrderInvert)
1479 {
1480 DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: !isOrderInvert\n");
1481
1482 for (; TotalXferLines < wWantedTotalLines;)
1483 {
1484 if (g_dwTotalTotalXferLines >= g_SWHeight)
1485 {
1486 pthread_cancel (g_threadid_readimage);
1487 pthread_join (g_threadid_readimage, NULL);
1488 DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: thread exit\n");
1489
1490 *wLinesCount = TotalXferLines;
1491 g_isScanning = FALSE;
1492 return TRUE;
1493 }
1494
1495 if (GetScannedLines () > g_wtheReadyLines)
1496 {
1497 wRLinePos = g_wtheReadyLines % g_wMaxScanLines;
1498 wGLinePos =
1499 (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
1500 wBLinePos =
1501 (g_wtheReadyLines - g_wLineDistance * 2) % g_wMaxScanLines;
1502
1503 for (i = 0; i < g_SWWidth; i++)
1504 {
1505 byRed =
1506 *(g_lpReadImageHead + wRLinePos * g_BytesPerRow + i * 3 +
1507 0);
1508 bNextPixel =
1509 *(g_lpReadImageHead + wRLinePos * g_BytesPerRow +
1510 (i + 1) * 3 + 0);
1511 byRed = (byRed + bNextPixel) >> 1;
1512
1513 byGreen =
1514 *(g_lpReadImageHead + wGLinePos * g_BytesPerRow + i * 3 +
1515 1);
1516 bNextPixel =
1517 *(g_lpReadImageHead + wGLinePos * g_BytesPerRow +
1518 (i + 1) * 3 + 1);
1519 byGreen = (byGreen + bNextPixel) >> 1;
1520
1521 byBlue =
1522 *(g_lpReadImageHead + wBLinePos * g_BytesPerRow + i * 3 +
1523 2);
1524 bNextPixel =
1525 *(g_lpReadImageHead + wBLinePos * g_BytesPerRow +
1526 (i + 1) * 3 + 2);
1527 byBlue = (byBlue + bNextPixel) >> 1;
1528
1529 #ifdef ENABLE_GAMMA
1530 tempR = (unsigned short) ((byRed << 4) | QBET4 (byBlue, byGreen));
1531 tempG = (unsigned short) ((byGreen << 4) | QBET4 (byRed, byBlue));
1532 tempB = (unsigned short) ((byBlue << 4) | QBET4 (byGreen, byRed));
1533
1534 *(lpLine + i * 3 + 0) =
1535 (unsigned char) (*(g_pGammaTable + tempR));
1536 *(lpLine + i * 3 + 1) =
1537 (unsigned char) (*(g_pGammaTable + 4096 + tempG));
1538 *(lpLine + i * 3 + 2) =
1539 (unsigned char) (*(g_pGammaTable + 8192 + tempB));
1540 #else
1541 *(lpLine + i * 3 + 0) = (unsigned char) byRed;
1542 *(lpLine + i * 3 + 1) = (unsigned char) byGreen;
1543 *(lpLine + i * 3 + 2) = (unsigned char) byBlue;
1544 #endif
1545 }
1546
1547 TotalXferLines++;
1548 g_dwTotalTotalXferLines++;
1549 lpLine += g_SWBytesPerRow;
1550 AddReadyLines ();
1551
1552 DBG (DBG_FUNC,
1553 "MustScanner_GetRgb24BitLine: g_dwTotalTotalXferLines=%d,g_SWHeight=%d\n",
1554 g_dwTotalTotalXferLines, g_SWHeight);
1555 DBG (DBG_FUNC,
1556 "MustScanner_GetRgb24BitLine: g_SWBytesPerRow=%d\n",
1557 g_SWBytesPerRow);
1558 }
1559 if (g_isCanceled)
1560 {
1561 pthread_cancel (g_threadid_readimage);
1562 pthread_join (g_threadid_readimage, NULL);
1563 DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: thread exit\n");
1564
1565 break;
1566 }
1567 }
1568 }
1569 else
1570 {
1571 DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: isOrderInvert is TRUE\n");
1572 for (; TotalXferLines < wWantedTotalLines;)
1573 {
1574 if (g_dwTotalTotalXferLines >= g_SWHeight)
1575 {
1576 pthread_cancel (g_threadid_readimage);
1577 pthread_join (g_threadid_readimage, NULL);
1578 DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: thread exit\n");
1579
1580 *wLinesCount = TotalXferLines;
1581 g_isScanning = FALSE;
1582 return TRUE;
1583 }
1584
1585 if (GetScannedLines () > g_wtheReadyLines)
1586 {
1587 wRLinePos = g_wtheReadyLines % g_wMaxScanLines;
1588 wGLinePos =
1589 (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
1590 wBLinePos =
1591 (g_wtheReadyLines - g_wLineDistance * 2) % g_wMaxScanLines;
1592
1593 for (i = 0; i < g_SWWidth; i++)
1594 {
1595 DBG (DBG_FUNC,
1596 "MustScanner_GetRgb24BitLine: before byRed\n");
1597 byRed =
1598 *(g_lpReadImageHead + wRLinePos * g_BytesPerRow + i * 3 +
1599 0);
1600 bNextPixel = *(g_lpReadImageHead + wRLinePos * g_BytesPerRow + (i + 1) * 3 + 0); /*R-channel */
1601 byRed = (byRed + bNextPixel) >> 1;
1602
1603 DBG (DBG_FUNC,
1604 "MustScanner_GetRgb24BitLine: before byGreen\n");
1605
1606 byGreen =
1607 *(g_lpReadImageHead + wGLinePos * g_BytesPerRow + i * 3 +
1608 1);
1609 bNextPixel = *(g_lpReadImageHead + wGLinePos * g_BytesPerRow + (i + 1) * 3 + 1); /*G-channel */
1610 byGreen = (byGreen + bNextPixel) >> 1;
1611
1612 DBG (DBG_FUNC,
1613 "MustScanner_GetRgb24BitLine: before byBlue\n");
1614
1615 byBlue =
1616 *(g_lpReadImageHead + wBLinePos * g_BytesPerRow + i * 3 +
1617 2);
1618 bNextPixel = *(g_lpReadImageHead + wBLinePos * g_BytesPerRow + (i + 1) * 3 + 2); /*B-channel */
1619 byBlue = (byBlue + bNextPixel) >> 1;
1620
1621
1622 DBG (DBG_FUNC,
1623 "MustScanner_GetRgb24BitLine: before set lpLine\n");
1624 DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: i=%d\n", i);
1625 #ifdef ENABLE_GAMMA
1626 *(lpLine + i * 3 + 2) =
1627 (unsigned
1628 char) (*(g_pGammaTable +
1629 (unsigned short) ((byRed << 4) |
1630 QBET4 (byBlue, byGreen))));
1631 *(lpLine + i * 3 + 1) =
1632 (unsigned
1633 char) (*(g_pGammaTable + 4096 +
1634 (unsigned short) ((byGreen << 4) |
1635 QBET4 (byRed, byBlue))));
1636 *(lpLine + i * 3 + 0) =
1637 (unsigned
1638 char) (*(g_pGammaTable + 8192 +
1639 (unsigned short) ((byBlue << 4) |
1640 QBET4 (byGreen, byRed))));
1641 #else
1642 *(lpLine + i * 3 + 2) = (unsigned char) byRed;
1643 *(lpLine + i * 3 + 1) = (unsigned char) byGreen;
1644 *(lpLine + i * 3 + 0) = (unsigned char) byBlue;
1645 #endif
1646 }
1647
1648 TotalXferLines++;
1649 g_dwTotalTotalXferLines++;
1650 lpLine += g_SWBytesPerRow;
1651 AddReadyLines ();
1652
1653 DBG (DBG_FUNC,
1654 "MustScanner_GetRgb24BitLine: g_dwTotalTotalXferLines=%d,g_SWHeight=%d\n",
1655 g_dwTotalTotalXferLines, g_SWHeight);
1656 DBG (DBG_FUNC,
1657 "MustScanner_GetRgb24BitLine: g_SWBytesPerRow=%d\n",
1658 g_SWBytesPerRow);
1659 }
1660 if (g_isCanceled)
1661 {
1662 pthread_cancel (g_threadid_readimage);
1663 pthread_join (g_threadid_readimage, NULL);
1664 DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine: thread exit\n");
1665
1666 break;
1667 }
1668 } /*end for */
1669 }
1670
1671 *wLinesCount = TotalXferLines;
1672 g_isScanning = FALSE;
1673
1674 DBG (DBG_FUNC,
1675 "MustScanner_GetRgb24BitLine: leave MustScanner_GetRgb24BitLine\n");
1676 return TRUE;
1677 }
1678
1679 /**********************************************************************
1680 Author: Jack Date: 2005/05/15
1681 Routine Description:
1682 Repair line when double CCD and color is 24bit
1683 Parameters:
1684 lpLine: point to image be repaired
1685 isOrderInvert: RGB or BGR
1686 wLinesCount: how many line be repaired
1687 Return value:
1688 if the operation is success
1689 return TRUE
1690 else
1691 return FALSE
1692 ***********************************************************************/
1693 static SANE_Bool
MustScanner_GetRgb24BitLine1200DPI(SANE_Byte * lpLine,SANE_Bool isOrderInvert,unsigned short * wLinesCount)1694 MustScanner_GetRgb24BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
1695 unsigned short * wLinesCount)
1696 {
1697 unsigned short wWantedTotalLines;
1698 unsigned short TotalXferLines;
1699 unsigned short wRLinePosOdd = 0;
1700 unsigned short wGLinePosOdd = 0;
1701 unsigned short wBLinePosOdd = 0;
1702 unsigned short wRLinePosEven = 0;
1703 unsigned short wGLinePosEven = 0;
1704 unsigned short wBLinePosEven = 0;
1705 SANE_Byte byRed;
1706 SANE_Byte byGreen;
1707 SANE_Byte byBlue;
1708 SANE_Byte bNextPixel = 0;
1709 unsigned short i;
1710
1711 DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine1200DPI: call in\n");
1712
1713 g_isCanceled = FALSE;
1714 g_isScanning = TRUE;
1715 TotalXferLines = 0;
1716 wWantedTotalLines = *wLinesCount;
1717
1718 if (g_bFirstReadImage)
1719 {
1720 pthread_create (&g_threadid_readimage, NULL,
1721 MustScanner_ReadDataFromScanner, NULL);
1722 DBG (DBG_FUNC, "MustScanner_GetRgb24BitLine1200DPI: thread create\n");
1723
1724 g_bFirstReadImage = FALSE;
1725 }
1726
1727 if (!isOrderInvert)
1728 {
1729 for (; TotalXferLines < wWantedTotalLines;)
1730 {
1731 if (g_dwTotalTotalXferLines >= g_SWHeight)
1732 {
1733 DBG (DBG_FUNC,
1734 "MustScanner_GetRgb24BitLine1200DPI: g_dwTotalTotalXferLines=%d\n",
1735 g_dwTotalTotalXferLines);
1736 DBG (DBG_FUNC,
1737 "MustScanner_GetRgb24BitLine1200DPI: g_Height=%d\n",
1738 g_Height);
1739
1740 pthread_cancel (g_threadid_readimage);
1741 pthread_join (g_threadid_readimage, NULL);
1742 DBG (DBG_FUNC,
1743 "MustScanner_GetRgb24BitLine1200DPI: thread exit\n");
1744
1745 *wLinesCount = TotalXferLines;
1746 g_isScanning = FALSE;
1747 return TRUE;
1748 }
1749
1750 if (GetScannedLines () > g_wtheReadyLines)
1751 {
1752 if (ST_Reflective == g_ScanType)
1753 {
1754 wRLinePosOdd =
1755 (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
1756 wGLinePosOdd =
1757 (g_wtheReadyLines - g_wLineDistance -
1758 g_wPixelDistance) % g_wMaxScanLines;
1759 wBLinePosOdd =
1760 (g_wtheReadyLines - g_wLineDistance * 2 -
1761 g_wPixelDistance) % g_wMaxScanLines;
1762 wRLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
1763 wGLinePosEven =
1764 (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
1765 wBLinePosEven =
1766 (g_wtheReadyLines -
1767 g_wLineDistance * 2) % g_wMaxScanLines;
1768 }
1769 else
1770 {
1771 wRLinePosEven =
1772 (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
1773 wGLinePosEven =
1774 (g_wtheReadyLines - g_wLineDistance -
1775 g_wPixelDistance) % g_wMaxScanLines;
1776 wBLinePosEven =
1777 (g_wtheReadyLines - g_wLineDistance * 2 -
1778 g_wPixelDistance) % g_wMaxScanLines;
1779 wRLinePosOdd = (g_wtheReadyLines) % g_wMaxScanLines;
1780 wGLinePosOdd =
1781 (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
1782 wBLinePosOdd =
1783 (g_wtheReadyLines -
1784 g_wLineDistance * 2) % g_wMaxScanLines;
1785 }
1786
1787
1788
1789 for (i = 0; i < g_SWWidth;)
1790 {
1791 if ((i + 1) != g_SWWidth)
1792 {
1793 byRed =
1794 *(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
1795 i * 3 + 0);
1796 bNextPixel = *(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow + (i + 1) * 3 + 0); /*R-channel */
1797 byRed = (byRed + bNextPixel) >> 1;
1798
1799 byGreen =
1800 *(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
1801 i * 3 + 1);
1802 bNextPixel = *(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow + (i + 1) * 3 + 1); /*G-channel */
1803 byGreen = (byGreen + bNextPixel) >> 1;
1804
1805 byBlue =
1806 *(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
1807 i * 3 + 2);
1808 bNextPixel = *(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow + (i + 1) * 3 + 2); /*B-channel */
1809 byBlue = (byBlue + bNextPixel) >> 1;
1810 #ifdef ENABLE_GAMMA
1811 *(lpLine + i * 3 + 0) =
1812 (unsigned
1813 char) (*(g_pGammaTable +
1814 (unsigned short) ((byRed << 4) |
1815 QBET4 (byBlue, byGreen))));
1816 *(lpLine + i * 3 + 1) =
1817 (unsigned
1818 char) (*(g_pGammaTable + 4096 +
1819 (unsigned short) ((byGreen << 4) |
1820 QBET4 (byRed, byBlue))));
1821 *(lpLine + i * 3 + 2) =
1822 (unsigned
1823 char) (*(g_pGammaTable + 8192 +
1824 (unsigned short) ((byBlue << 4) |
1825 QBET4 (byGreen, byRed))));
1826 #else
1827 *(lpLine + i * 3 + 0) = (unsigned char) byRed;
1828 *(lpLine + i * 3 + 1) = (unsigned char) byGreen;
1829 *(lpLine + i * 3 + 2) = (unsigned char) byBlue;
1830 #endif
1831
1832 i++;
1833 if (i >= g_SWWidth)
1834 {
1835 break;
1836 }
1837
1838 byRed =
1839 *(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
1840 i * 3 + 0);
1841 bNextPixel =
1842 *(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
1843 (i + 1) * 3 + 0);
1844 byRed = (byRed + bNextPixel) >> 1;
1845
1846 byGreen =
1847 *(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
1848 i * 3 + 1);
1849 bNextPixel =
1850 *(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
1851 (i + 1) * 3 + 1);
1852 byGreen = (byGreen + bNextPixel) >> 1;
1853
1854 byBlue =
1855 *(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
1856 i * 3 + 2);
1857 bNextPixel =
1858 *(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
1859 (i + 1) * 3 + 2);
1860 byBlue = (byBlue + bNextPixel) >> 1;
1861 #ifdef ENABLE_GAMMA
1862 *(lpLine + i * 3 + 0) =
1863 (unsigned
1864 char) (*(g_pGammaTable +
1865 (unsigned short) ((byRed << 4) |
1866 QBET4 (byBlue, byGreen))));
1867 *(lpLine + i * 3 + 1) =
1868 (unsigned
1869 char) (*(g_pGammaTable + 4096 +
1870 (unsigned short) ((byGreen << 4) |
1871 QBET4 (byRed, byBlue))));
1872 *(lpLine + i * 3 + 2) =
1873 (unsigned
1874 char) (*(g_pGammaTable + 8192 +
1875 (unsigned short) ((byBlue << 4) |
1876 QBET4 (byGreen, byRed))));
1877 #else
1878 *(lpLine + i * 3 + 0) = (unsigned char) byRed;
1879 *(lpLine + i * 3 + 1) = (unsigned char) byGreen;
1880 *(lpLine + i * 3 + 2) = (unsigned char) byBlue;
1881 #endif
1882 i++;
1883 }
1884 }
1885
1886
1887 TotalXferLines++;
1888 g_dwTotalTotalXferLines++;
1889 lpLine += g_SWBytesPerRow;
1890 AddReadyLines ();
1891
1892 DBG (DBG_FUNC,
1893 "MustScanner_GetRgb24BitLine1200DPI: g_dwTotalTotalXferLines=%d\n",
1894 g_dwTotalTotalXferLines);
1895 DBG (DBG_FUNC,
1896 "MustScanner_GetRgb24BitLine1200DPI: g_Height=%d\n",
1897 g_Height);
1898
1899 }
1900 if (g_isCanceled)
1901 {
1902 pthread_cancel (g_threadid_readimage);
1903 pthread_join (g_threadid_readimage, NULL);
1904 DBG (DBG_FUNC,
1905 "MustScanner_GetRgb24BitLine1200DPI: thread exit\n");
1906
1907 break;
1908 }
1909
1910 }
1911 }
1912 else
1913 {
1914
1915 for (; TotalXferLines < wWantedTotalLines;)
1916 {
1917 if (g_dwTotalTotalXferLines >= g_SWHeight)
1918 {
1919 DBG (DBG_FUNC,
1920 "MustScanner_GetRgb24BitLine1200DPI: g_dwTotalTotalXferLines=%d\n",
1921 g_dwTotalTotalXferLines);
1922 DBG (DBG_FUNC,
1923 "MustScanner_GetRgb24BitLine1200DPI: g_Height=%d\n",
1924 g_Height);
1925
1926 pthread_cancel (g_threadid_readimage);
1927 pthread_join (g_threadid_readimage, NULL);
1928 DBG (DBG_FUNC,
1929 "MustScanner_GetRgb24BitLine1200DPI: thread exit\n");
1930
1931 *wLinesCount = TotalXferLines;
1932 g_isScanning = FALSE;
1933 return TRUE;
1934 }
1935
1936 if (GetScannedLines () > g_wtheReadyLines)
1937 {
1938 if (ST_Reflective == g_ScanType)
1939 {
1940 wRLinePosOdd =
1941 (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
1942 wGLinePosOdd =
1943 (g_wtheReadyLines - g_wLineDistance -
1944 g_wPixelDistance) % g_wMaxScanLines;
1945 wBLinePosOdd =
1946 (g_wtheReadyLines - g_wLineDistance * 2 -
1947 g_wPixelDistance) % g_wMaxScanLines;
1948 wRLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
1949 wGLinePosEven =
1950 (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
1951 wBLinePosEven =
1952 (g_wtheReadyLines -
1953 g_wLineDistance * 2) % g_wMaxScanLines;
1954 }
1955 else
1956 {
1957 wRLinePosEven =
1958 (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
1959 wGLinePosEven =
1960 (g_wtheReadyLines - g_wLineDistance -
1961 g_wPixelDistance) % g_wMaxScanLines;
1962 wBLinePosEven =
1963 (g_wtheReadyLines - g_wLineDistance * 2 -
1964 g_wPixelDistance) % g_wMaxScanLines;
1965 wRLinePosOdd = (g_wtheReadyLines) % g_wMaxScanLines;
1966 wGLinePosOdd =
1967 (g_wtheReadyLines - g_wLineDistance) % g_wMaxScanLines;
1968 wBLinePosOdd =
1969 (g_wtheReadyLines -
1970 g_wLineDistance * 2) % g_wMaxScanLines;
1971 }
1972
1973 for (i = 0; i < g_SWWidth;)
1974 {
1975 if ((i + 1) != g_SWWidth)
1976 {
1977 byRed =
1978 *(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
1979 i * 3 + 0);
1980 bNextPixel =
1981 *(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
1982 (i + 1) * 3 + 0);
1983 byRed = (byRed + bNextPixel) >> 1;
1984
1985 byGreen =
1986 *(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
1987 i * 3 + 1);
1988 bNextPixel =
1989 *(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
1990 (i + 1) * 3 + 1);
1991 byGreen = (byGreen + bNextPixel) >> 1;
1992
1993 byBlue =
1994 *(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
1995 i * 3 + 2);
1996 bNextPixel =
1997 *(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
1998 (i + 1) * 3 + 2);
1999 byBlue = (byBlue + bNextPixel) >> 1;
2000
2001 #ifdef ENABLE_GAMMA
2002 *(lpLine + i * 3 + 2) =
2003 (unsigned
2004 char) (*(g_pGammaTable +
2005 (unsigned short) ((byRed << 4) |
2006 QBET4 (byBlue, byGreen))));
2007 *(lpLine + i * 3 + 1) =
2008 (unsigned
2009 char) (*(g_pGammaTable + 4096 +
2010 (unsigned short) ((byGreen << 4) |
2011 QBET4 (byRed, byBlue))));
2012 *(lpLine + i * 3 + 0) =
2013 (unsigned
2014 char) (*(g_pGammaTable + 8192 +
2015 (unsigned short) ((byBlue << 4) |
2016 QBET4 (byGreen, byRed))));
2017 #else
2018 *(lpLine + i * 3 + 2) = (unsigned char) byRed;
2019 *(lpLine + i * 3 + 1) = (unsigned char) byGreen;
2020 *(lpLine + i * 3 + 0) = (unsigned char) byBlue;
2021 #endif
2022 i++;
2023 if (i >= g_SWWidth)
2024 {
2025 break;
2026 }
2027
2028 byRed =
2029 *(g_lpReadImageHead + wRLinePosEven * g_BytesPerRow +
2030 i * 3 + 0);
2031 bNextPixel =
2032 *(g_lpReadImageHead + wRLinePosOdd * g_BytesPerRow +
2033 (i + 1) * 3 + 0);
2034 byRed = (byRed + bNextPixel) >> 1;
2035
2036 byGreen =
2037 *(g_lpReadImageHead + wGLinePosEven * g_BytesPerRow +
2038 i * 3 + 1);
2039 bNextPixel =
2040 *(g_lpReadImageHead + wGLinePosOdd * g_BytesPerRow +
2041 (i + 1) * 3 + 1);
2042 byGreen = (byGreen + bNextPixel) >> 1;
2043
2044 byBlue =
2045 *(g_lpReadImageHead + wBLinePosEven * g_BytesPerRow +
2046 i * 3 + 2);
2047 bNextPixel =
2048 *(g_lpReadImageHead + wBLinePosOdd * g_BytesPerRow +
2049 (i + 1) * 3 + 2);
2050 byBlue = (byBlue + bNextPixel) >> 1;
2051 #ifdef ENABLE_GAMMA
2052 *(lpLine + i * 3 + 2) =
2053 (unsigned
2054 char) (*(g_pGammaTable +
2055 (unsigned short) ((byRed << 4) |
2056 QBET4 (byBlue, byGreen))));
2057 *(lpLine + i * 3 + 1) =
2058 (unsigned
2059 char) (*(g_pGammaTable + 4096 +
2060 (unsigned short) ((byGreen << 4) |
2061 QBET4 (byRed, byBlue))));
2062 *(lpLine + i * 3 + 0) =
2063 (unsigned
2064 char) (*(g_pGammaTable + 8192 +
2065 (unsigned short) ((byBlue << 4) |
2066 QBET4 (byGreen, byRed))));
2067 #else
2068 *(lpLine + i * 3 + 2) = (unsigned char) byRed;
2069 *(lpLine + i * 3 + 1) = (unsigned char) byGreen;
2070 *(lpLine + i * 3 + 0) = (unsigned char) byBlue;
2071 #endif
2072 i++;
2073 }
2074 }
2075
2076 TotalXferLines++;
2077 g_dwTotalTotalXferLines++;
2078 lpLine += g_SWBytesPerRow;
2079 AddReadyLines ();
2080
2081 DBG (DBG_FUNC,
2082 "MustScanner_GetRgb24BitLine1200DPI: g_dwTotalTotalXferLines=%d\n",
2083 g_dwTotalTotalXferLines);
2084 DBG (DBG_FUNC,
2085 "MustScanner_GetRgb24BitLine1200DPI: g_Height=%d\n",
2086 g_Height);
2087
2088 }
2089 if (g_isCanceled)
2090 {
2091 pthread_cancel (g_threadid_readimage);
2092 pthread_join (g_threadid_readimage, NULL);
2093 DBG (DBG_FUNC,
2094 "MustScanner_GetRgb24BitLine1200DPI: thread exit\n");
2095
2096
2097 break;
2098 }
2099 }
2100 }
2101
2102 *wLinesCount = TotalXferLines;
2103 g_isScanning = FALSE;
2104
2105 DBG (DBG_FUNC,
2106 "MustScanner_GetRgb24BitLine1200DPI: leave MustScanner_GetRgb24BitLine1200DPI\n");
2107 return TRUE;
2108 }
2109
2110 /**********************************************************************
2111 Author: Jack Date: 2005/05/15
2112 Routine Description:
2113 Repair line when single CCD and color is 16bit
2114 Parameters:
2115 lpLine: point to image be repaired
2116 isOrderInvert: RGB or BGR
2117 wLinesCount: how many line be repaired
2118 Return value:
2119 if the operation is success
2120 return TRUE
2121 else
2122 return FALSE
2123 ***********************************************************************/
2124 static SANE_Bool
MustScanner_GetMono16BitLine(SANE_Byte * lpLine,SANE_Bool isOrderInvert,unsigned short * wLinesCount)2125 MustScanner_GetMono16BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
2126 unsigned short * wLinesCount)
2127 {
2128 unsigned short wWantedTotalLines;
2129 unsigned short TotalXferLines;
2130 unsigned int wTempData;
2131
2132 unsigned short wLinePos = 0;
2133 unsigned short i;
2134
2135 (void) isOrderInvert;
2136
2137 DBG (DBG_FUNC, "MustScanner_GetMono16BitLine: call in\n");
2138
2139 TotalXferLines = 0;
2140 g_isCanceled = FALSE;
2141 g_isScanning = TRUE;
2142 wWantedTotalLines = *wLinesCount;
2143
2144 if (g_bFirstReadImage)
2145 {
2146 pthread_create (&g_threadid_readimage, NULL,
2147 MustScanner_ReadDataFromScanner, NULL);
2148 DBG (DBG_FUNC, "MustScanner_GetMono16BitLine: thread create\n");
2149 g_bFirstReadImage = FALSE;
2150 }
2151
2152 for (; TotalXferLines < wWantedTotalLines;)
2153 {
2154
2155 if (g_dwTotalTotalXferLines >= g_SWHeight)
2156 {
2157 pthread_cancel (g_threadid_readimage);
2158 pthread_join (g_threadid_readimage, NULL);
2159 DBG (DBG_FUNC, "MustScanner_GetMono16BitLine: thread exit\n");
2160
2161 *wLinesCount = TotalXferLines;
2162 g_isScanning = FALSE;
2163 return TRUE;
2164 }
2165
2166 if (GetScannedLines () > g_wtheReadyLines)
2167 {
2168 wLinePos = g_wtheReadyLines % g_wMaxScanLines;
2169
2170 for (i = 0; i < g_SWWidth; i++)
2171 {
2172 wTempData =
2173 *(g_lpReadImageHead + wLinePos * g_BytesPerRow + i * 2 + 0);
2174 wTempData +=
2175 *(g_lpReadImageHead + wLinePos * g_BytesPerRow + i * 2 +
2176 1) << 8;
2177 *(lpLine + i * 2 + 0) = LOBYTE (g_pGammaTable[wTempData]);
2178 *(lpLine + i * 2 + 1) = HIBYTE (g_pGammaTable[wTempData]);
2179 }
2180
2181 TotalXferLines++;
2182 g_dwTotalTotalXferLines++;
2183
2184 lpLine += g_SWBytesPerRow;
2185 AddReadyLines ();
2186 }
2187 if (g_isCanceled)
2188 {
2189 pthread_cancel (g_threadid_readimage);
2190 pthread_join (g_threadid_readimage, NULL);
2191 DBG (DBG_FUNC, "MustScanner_GetMono16BitLine: thread exit\n");
2192
2193 break;
2194 }
2195 }
2196
2197 *wLinesCount = TotalXferLines;
2198 g_isScanning = FALSE;
2199
2200 DBG (DBG_FUNC,
2201 "MustScanner_GetMono16BitLine: leave MustScanner_GetMono16BitLine\n");
2202 return TRUE;
2203 }
2204
2205 /**********************************************************************
2206 Author: Jack Date: 2005/05/15
2207 Routine Description:
2208 Repair line when double CCD and color is 16bit
2209 Parameters:
2210 lpLine: point to image be repaired
2211 isOrderInvert: RGB or BGR
2212 wLinesCount: how many line be repaired
2213 Return value:
2214 if the operation is success
2215 return TRUE
2216 else
2217 return FALSE
2218 ***********************************************************************/
2219 static SANE_Bool
MustScanner_GetMono16BitLine1200DPI(SANE_Byte * lpLine,SANE_Bool isOrderInvert,unsigned short * wLinesCount)2220 MustScanner_GetMono16BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
2221 unsigned short * wLinesCount)
2222 {
2223 unsigned short wWantedTotalLines;
2224 unsigned short TotalXferLines;
2225 unsigned int dwTempData;
2226 unsigned short wLinePosOdd = 0;
2227 unsigned short wLinePosEven = 0;
2228 unsigned short i;
2229 SANE_Byte * lpTemp = lpLine;
2230
2231 (void) isOrderInvert;
2232 DBG (DBG_FUNC, "MustScanner_GetMono16BitLine1200DPI: call in\n");
2233
2234 TotalXferLines = 0;
2235 g_isCanceled = FALSE;
2236 g_isScanning = TRUE;
2237 wWantedTotalLines = *wLinesCount;
2238
2239 if (g_bFirstReadImage)
2240 {
2241 pthread_create (&g_threadid_readimage, NULL,
2242 MustScanner_ReadDataFromScanner, NULL);
2243 DBG (DBG_FUNC, "MustScanner_GetMono16BitLine1200DPI: thread create\n");
2244 g_bFirstReadImage = FALSE;
2245 }
2246
2247 for (; TotalXferLines < wWantedTotalLines;)
2248 {
2249 if (g_dwTotalTotalXferLines >= g_SWHeight)
2250 {
2251 pthread_cancel (g_threadid_readimage);
2252 pthread_join (g_threadid_readimage, NULL);
2253 DBG (DBG_FUNC,
2254 "MustScanner_GetMono16BitLine1200DPI: thread exit\n");
2255
2256 *wLinesCount = TotalXferLines;
2257 g_isScanning = FALSE;
2258 return TRUE;
2259 }
2260
2261 if (GetScannedLines () > g_wtheReadyLines)
2262 {
2263 if (ST_Reflective == g_ScanType)
2264 {
2265 wLinePosOdd =
2266 (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
2267 wLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
2268 }
2269 else
2270 {
2271 wLinePosEven =
2272 (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
2273 wLinePosOdd = (g_wtheReadyLines) % g_wMaxScanLines;
2274 }
2275
2276
2277 for (i = 0; i < g_SWWidth;)
2278 {
2279 if ((i + 1) != g_SWWidth)
2280 {
2281 dwTempData =
2282 (unsigned int) (*
2283 (g_lpReadImageHead +
2284 wLinePosOdd * g_BytesPerRow + i * 2 + 0));
2285 dwTempData +=
2286 (unsigned int) (*
2287 (g_lpReadImageHead +
2288 wLinePosOdd * g_BytesPerRow + i * 2 + 1) << 8);
2289 dwTempData +=
2290 (unsigned int) (*
2291 (g_lpReadImageHead +
2292 wLinePosEven * g_BytesPerRow + (i + 1) * 2 +
2293 0));
2294 dwTempData +=
2295 (unsigned int) (*
2296 (g_lpReadImageHead +
2297 wLinePosEven * g_BytesPerRow + (i + 1) * 2 +
2298 1) << 8);
2299 dwTempData = g_pGammaTable[dwTempData >> 1];
2300 *(lpLine + i * 2 + 0) = LOBYTE ((unsigned short) dwTempData);
2301 *(lpLine + i * 2 + 1) = HIBYTE ((unsigned short) dwTempData);
2302 i++;
2303 if (i >= g_SWWidth)
2304 {
2305 break;
2306 }
2307
2308 dwTempData =
2309 (unsigned int) (*
2310 (g_lpReadImageHead +
2311 wLinePosEven * g_BytesPerRow + i * 2 + 0));
2312 dwTempData +=
2313 (unsigned int) (*
2314 (g_lpReadImageHead +
2315 wLinePosEven * g_BytesPerRow + i * 2 + 1) << 8);
2316 dwTempData +=
2317 (unsigned int) (*
2318 (g_lpReadImageHead +
2319 wLinePosOdd * g_BytesPerRow + (i + 1) * 2 + 0));
2320 dwTempData +=
2321 (unsigned int) (*
2322 (g_lpReadImageHead +
2323 wLinePosOdd * g_BytesPerRow + (i + 1) * 2 +
2324 1) << 8);
2325 dwTempData = g_pGammaTable[dwTempData >> 1];
2326 *(lpLine + i * 2 + 0) = LOBYTE ((unsigned short) dwTempData);
2327 *(lpLine + i * 2 + 1) = HIBYTE ((unsigned short) dwTempData);
2328 i++;
2329 }
2330 }
2331
2332 TotalXferLines++;
2333 g_dwTotalTotalXferLines++;
2334 lpLine += g_SWBytesPerRow;
2335 AddReadyLines ();
2336 }
2337 if (g_isCanceled)
2338 {
2339 pthread_cancel (g_threadid_readimage);
2340 pthread_join (g_threadid_readimage, NULL);
2341 DBG (DBG_FUNC,
2342 "MustScanner_GetMono16BitLine1200DPI: thread exit\n");
2343
2344 break;
2345 }
2346 }
2347
2348 *wLinesCount = TotalXferLines;
2349 g_isScanning = FALSE;
2350
2351 /*for modify the last point */
2352 if (g_bIsFirstReadBefData)
2353 {
2354 g_lpBefLineImageData = (SANE_Byte *) malloc (g_SWBytesPerRow);
2355 if (NULL == g_lpBefLineImageData)
2356 {
2357 return FALSE;
2358 }
2359 memset (g_lpBefLineImageData, 0, g_SWBytesPerRow);
2360 memcpy (g_lpBefLineImageData, lpTemp, g_SWBytesPerRow);
2361 g_bIsFirstReadBefData = FALSE;
2362 }
2363
2364 ModifyLinePoint (lpTemp, g_lpBefLineImageData, g_SWBytesPerRow,
2365 wWantedTotalLines, 2, 4);
2366
2367 memcpy (g_lpBefLineImageData,
2368 lpTemp + (wWantedTotalLines - 1) * g_SWBytesPerRow,
2369 g_SWBytesPerRow);
2370 g_dwAlreadyGetLines += wWantedTotalLines;
2371 if (g_dwAlreadyGetLines >= g_SWHeight)
2372 {
2373 DBG (DBG_FUNC,
2374 "MustScanner_GetMono16BitLine1200DPI: free before line data!\n");
2375 free (g_lpBefLineImageData);
2376 g_lpBefLineImageData = NULL;
2377 g_dwAlreadyGetLines = 0;
2378 g_bIsFirstReadBefData = TRUE;
2379 }
2380
2381 DBG (DBG_FUNC,
2382 "MustScanner_GetMono16BitLine1200DPI: leave MustScanner_GetMono16BitLine1200DPI\n");
2383 return TRUE;
2384 }
2385
2386 /**********************************************************************
2387 Author: Jack Date: 2005/05/15
2388 Routine Description:
2389 Repair line when single CCD and color is 8bit
2390 Parameters:
2391 lpLine: point to image be repaired
2392 isOrderInvert: RGB or BGR
2393 wLinesCount: how many line be repaired
2394 Return value:
2395 if the operation is success
2396 return TRUE
2397 else
2398 return FALSE
2399 ***********************************************************************/
2400 static SANE_Bool
MustScanner_GetMono8BitLine(SANE_Byte * lpLine,SANE_Bool isOrderInvert,unsigned short * wLinesCount)2401 MustScanner_GetMono8BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
2402 unsigned short * wLinesCount)
2403 {
2404 unsigned short wWantedTotalLines;
2405 unsigned short TotalXferLines;
2406
2407 unsigned short i;
2408 unsigned short wLinePos = 0;
2409
2410 (void) isOrderInvert;
2411 DBG (DBG_FUNC, "MustScanner_GetMono8BitLine: call in\n");
2412
2413 TotalXferLines = 0;
2414 g_isCanceled = FALSE;
2415 g_isScanning = TRUE;
2416 wWantedTotalLines = *wLinesCount;
2417
2418 if (g_bFirstReadImage)
2419 {
2420 pthread_create (&g_threadid_readimage, NULL,
2421 MustScanner_ReadDataFromScanner, NULL);
2422 DBG (DBG_FUNC, "MustScanner_GetMono8BitLine: thread create\n");
2423 g_bFirstReadImage = FALSE;
2424 }
2425
2426 for (; TotalXferLines < wWantedTotalLines;)
2427 {
2428 if (g_dwTotalTotalXferLines >= g_SWHeight)
2429 {
2430 pthread_cancel (g_threadid_readimage);
2431 pthread_join (g_threadid_readimage, NULL);
2432 DBG (DBG_FUNC, "MustScanner_GetMono8BitLine: thread exit\n");
2433
2434 *wLinesCount = TotalXferLines;
2435 g_isScanning = FALSE;
2436 return TRUE;
2437 }
2438
2439 if (GetScannedLines () > g_wtheReadyLines)
2440 {
2441 wLinePos = g_wtheReadyLines % g_wMaxScanLines;
2442
2443 for (i = 0; i < g_SWWidth; i++)
2444 {
2445 *(lpLine + i) =
2446 (SANE_Byte) * (g_pGammaTable +
2447 (unsigned short) ((*
2448 (g_lpReadImageHead +
2449 wLinePos * g_BytesPerRow +
2450 i) << 4) | (rand () & 0x0f)));
2451 }
2452
2453 TotalXferLines++;
2454 g_dwTotalTotalXferLines++;
2455 lpLine += g_SWBytesPerRow;
2456 AddReadyLines ();
2457
2458 }
2459 if (g_isCanceled)
2460 {
2461 pthread_cancel (g_threadid_readimage);
2462 pthread_join (g_threadid_readimage, NULL);
2463 DBG (DBG_FUNC, "MustScanner_GetMono8BitLine: thread exit\n");
2464
2465 break;
2466 }
2467 }
2468
2469 *wLinesCount = TotalXferLines;
2470 g_isScanning = FALSE;
2471
2472 DBG (DBG_FUNC,
2473 "MustScanner_GetMono8BitLine: leave MustScanner_GetMono8BitLine\n");
2474 return TRUE;
2475 }
2476
2477 /**********************************************************************
2478 Author: Jack Date: 2005/05/15
2479 Routine Description:
2480 Repair line when double CCD and color is 8bit
2481 Parameters:
2482 lpLine: point to image be repaired
2483 isOrderInvert: RGB or BGR
2484 wLinesCount: how many line be repaired
2485 Return value:
2486 if the operation is success
2487 return TRUE
2488 else
2489 return FALSE
2490 ***********************************************************************/
2491 static SANE_Bool
MustScanner_GetMono8BitLine1200DPI(SANE_Byte * lpLine,SANE_Bool isOrderInvert,unsigned short * wLinesCount)2492 MustScanner_GetMono8BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
2493 unsigned short * wLinesCount)
2494 {
2495 SANE_Byte *lpTemp;
2496 unsigned short wWantedTotalLines;
2497 unsigned short TotalXferLines;
2498
2499 unsigned short wLinePosOdd = 0;
2500 unsigned short wLinePosEven = 0;
2501 SANE_Byte byGray;
2502 unsigned short i;
2503 SANE_Byte bNextPixel = 0;
2504
2505 (void) isOrderInvert;
2506 DBG (DBG_FUNC, "MustScanner_GetMono8BitLine1200DPI: call in\n");
2507
2508 TotalXferLines = 0;
2509 g_isCanceled = FALSE;
2510 g_isScanning = TRUE;
2511 wWantedTotalLines = *wLinesCount;
2512 lpTemp = lpLine;
2513
2514 if (g_bFirstReadImage)
2515 {
2516 pthread_create (&g_threadid_readimage, NULL,
2517 MustScanner_ReadDataFromScanner, NULL);
2518 DBG (DBG_FUNC, "MustScanner_GetMono8BitLine1200DPI: thread create\n");
2519 g_bFirstReadImage = FALSE;
2520 }
2521
2522 for (; TotalXferLines < wWantedTotalLines;)
2523 {
2524 if (g_dwTotalTotalXferLines >= g_SWHeight)
2525 {
2526 pthread_cancel (g_threadid_readimage);
2527 pthread_join (g_threadid_readimage, NULL);
2528 DBG (DBG_FUNC, "MustScanner_GetMono8BitLine1200DPI: thread exit\n");
2529
2530 *wLinesCount = TotalXferLines;
2531 g_isScanning = FALSE;
2532 return TRUE;
2533 }
2534
2535 if (GetScannedLines () > g_wtheReadyLines)
2536 {
2537 if (ST_Reflective == g_ScanType)
2538
2539 {
2540 wLinePosOdd =
2541 (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
2542 wLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
2543 }
2544 else
2545 {
2546 wLinePosEven =
2547 (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
2548 wLinePosOdd = (g_wtheReadyLines) % g_wMaxScanLines;
2549 }
2550
2551
2552 for (i = 0; i < g_SWWidth;)
2553 {
2554 if ((i + 1) != g_SWWidth)
2555 {
2556 byGray =
2557 *(g_lpReadImageHead + wLinePosOdd * g_BytesPerRow + i);
2558 bNextPixel =
2559 *(g_lpReadImageHead + wLinePosEven * g_BytesPerRow +
2560 (i + 1));
2561 byGray = (byGray + bNextPixel) >> 1;
2562
2563 *(lpLine + i) =
2564 (SANE_Byte) * (g_pGammaTable +
2565 (byGray << 4 | (rand () & 0x0f)));
2566 i++;
2567 if (i >= g_SWWidth)
2568 {
2569 break;
2570 }
2571
2572 byGray =
2573 *(g_lpReadImageHead + wLinePosEven * g_BytesPerRow + i);
2574 bNextPixel =
2575 *(g_lpReadImageHead + wLinePosOdd * g_BytesPerRow +
2576 (i + 1));
2577 byGray = (byGray + bNextPixel) >> 1;
2578
2579 *(lpLine + i) =
2580 (SANE_Byte) * (g_pGammaTable +
2581 (byGray << 4 | (rand () & 0x0f)));
2582 i++;
2583 }
2584 }
2585
2586 TotalXferLines++;
2587 g_dwTotalTotalXferLines++;
2588 lpLine += g_SWBytesPerRow;
2589 AddReadyLines ();
2590 }
2591 if (g_isCanceled)
2592 {
2593 pthread_cancel (g_threadid_readimage);
2594 pthread_join (g_threadid_readimage, NULL);
2595 DBG (DBG_FUNC, "MustScanner_GetMono8BitLine1200DPI: thread exit\n");
2596
2597 break;
2598 }
2599 }
2600
2601
2602 *wLinesCount = TotalXferLines;
2603 g_isScanning = FALSE;
2604
2605 /*for modify the last point */
2606 if (g_bIsFirstReadBefData)
2607 {
2608 g_lpBefLineImageData = (SANE_Byte *) malloc (g_SWBytesPerRow);
2609 if (NULL == g_lpBefLineImageData)
2610 {
2611 return FALSE;
2612 }
2613 memset (g_lpBefLineImageData, 0, g_SWBytesPerRow);
2614 memcpy (g_lpBefLineImageData, lpTemp, g_SWBytesPerRow);
2615 g_bIsFirstReadBefData = FALSE;
2616 }
2617
2618 ModifyLinePoint (lpTemp, g_lpBefLineImageData, g_SWBytesPerRow,
2619 wWantedTotalLines, 1, 4);
2620
2621 memcpy (g_lpBefLineImageData,
2622 lpTemp + (wWantedTotalLines - 1) * g_SWBytesPerRow,
2623 g_SWBytesPerRow);
2624 g_dwAlreadyGetLines += wWantedTotalLines;
2625 if (g_dwAlreadyGetLines >= g_SWHeight)
2626 {
2627 DBG (DBG_FUNC,
2628 "MustScanner_GetMono8BitLine1200DPI: free the before line data!\n");
2629 free (g_lpBefLineImageData);
2630 g_lpBefLineImageData = NULL;
2631 g_dwAlreadyGetLines = 0;
2632 g_bIsFirstReadBefData = TRUE;
2633 }
2634
2635 DBG (DBG_FUNC,
2636 "MustScanner_GetMono8BitLine1200DPI: leave MustScanner_GetMono8BitLine1200DPI\n");
2637 return TRUE;
2638 }
2639
2640 /**********************************************************************
2641 Author: Jack Date: 2005/05/15
2642 Routine Description:
2643 Repair line when single CCD and color is 1bit
2644 Parameters:
2645 lpLine: point to image be repaired
2646 isOrderInvert: RGB or BGR
2647 wLinesCount: how many line be repaired
2648 Return value:
2649 if the operation is success
2650 return TRUE
2651 else
2652 return FALSE
2653 ***********************************************************************/
2654 static SANE_Bool
MustScanner_GetMono1BitLine(SANE_Byte * lpLine,SANE_Bool isOrderInvert,unsigned short * wLinesCount)2655 MustScanner_GetMono1BitLine (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
2656 unsigned short * wLinesCount)
2657 {
2658 unsigned short wWantedTotalLines;
2659 unsigned short TotalXferLines;
2660 unsigned short wLinePos;
2661 unsigned short i;
2662
2663 (void) isOrderInvert;
2664
2665 DBG (DBG_FUNC, "MustScanner_GetMono1BitLine: call in\n");
2666
2667 g_isCanceled = FALSE;
2668 g_isScanning = TRUE;
2669 wWantedTotalLines = *wLinesCount;
2670
2671 if (g_bFirstReadImage)
2672 {
2673 pthread_create (&g_threadid_readimage, NULL,
2674 MustScanner_ReadDataFromScanner, NULL);
2675 DBG (DBG_FUNC, "MustScanner_GetMono1BitLine: thread create\n");
2676 g_bFirstReadImage = FALSE;
2677 }
2678
2679 memset (lpLine, 0, wWantedTotalLines * g_SWWidth / 8);
2680
2681 for (TotalXferLines = 0; TotalXferLines < wWantedTotalLines;)
2682
2683 {
2684 if (g_dwTotalTotalXferLines >= g_SWHeight)
2685 {
2686 pthread_cancel (g_threadid_readimage);
2687 pthread_join (g_threadid_readimage, NULL);
2688 DBG (DBG_FUNC, "MustScanner_GetMono1BitLine: thread exit\n");
2689
2690 *wLinesCount = TotalXferLines;
2691 g_isScanning = FALSE;
2692 return TRUE;
2693 }
2694
2695 if (GetScannedLines () > g_wtheReadyLines)
2696 {
2697 wLinePos = g_wtheReadyLines % g_wMaxScanLines;
2698
2699 for (i = 0; i < g_SWWidth; i++)
2700 {
2701 if (*(g_lpReadImageHead + wLinePos * g_BytesPerRow + i) >
2702 g_wLineartThreshold)
2703 {
2704 *(lpLine + i / 8) += (0x80 >> (i % 8));
2705 }
2706 }
2707
2708 TotalXferLines++;
2709 g_dwTotalTotalXferLines++;
2710 lpLine += (g_SWBytesPerRow / 8);
2711 AddReadyLines ();
2712 }
2713 if (g_isCanceled)
2714 {
2715 pthread_cancel (g_threadid_readimage);
2716 pthread_join (g_threadid_readimage, NULL);
2717 DBG (DBG_FUNC, "MustScanner_GetMono1BitLine: thread exit\n");
2718
2719 break;
2720 }
2721 }
2722
2723 *wLinesCount = TotalXferLines;
2724 g_isScanning = FALSE;
2725
2726 DBG (DBG_FUNC,
2727 "MustScanner_GetMono1BitLine: leave MustScanner_GetMono1BitLine\n");
2728 return TRUE;
2729 }
2730
2731 /**********************************************************************
2732 Author: Jack Date: 2005/05/15
2733 Routine Description:
2734 Repair line when double CCD and color is 1bit
2735 Parameters:
2736 lpLine: point to image be repaired
2737 isOrderInvert: RGB or BGR
2738 wLinesCount: how many line be repaired
2739 Return value:
2740 if the operation is success
2741 return TRUE
2742 else
2743 return FALSE
2744 ***********************************************************************/
2745 static SANE_Bool
MustScanner_GetMono1BitLine1200DPI(SANE_Byte * lpLine,SANE_Bool isOrderInvert,unsigned short * wLinesCount)2746 MustScanner_GetMono1BitLine1200DPI (SANE_Byte * lpLine, SANE_Bool isOrderInvert,
2747 unsigned short * wLinesCount)
2748 {
2749 unsigned short wWantedTotalLines;
2750 unsigned short TotalXferLines;
2751 unsigned short i;
2752 unsigned short wLinePosOdd;
2753 unsigned short wLinePosEven;
2754
2755 (void) isOrderInvert;
2756
2757 DBG (DBG_FUNC, "MustScanner_GetMono1BitLine1200DPI: call in\n");
2758
2759 g_isCanceled = FALSE;
2760 g_isScanning = TRUE;
2761 wWantedTotalLines = *wLinesCount;
2762
2763 if (g_bFirstReadImage)
2764 {
2765 pthread_create (&g_threadid_readimage, NULL,
2766 MustScanner_ReadDataFromScanner, NULL);
2767 DBG (DBG_FUNC, "MustScanner_GetMono1BitLine1200DPI: thread create\n");
2768 g_bFirstReadImage = FALSE;
2769 }
2770
2771 memset (lpLine, 0, wWantedTotalLines * g_SWWidth / 8);
2772
2773 for (TotalXferLines = 0; TotalXferLines < wWantedTotalLines;)
2774 {
2775 if (g_dwTotalTotalXferLines >= g_SWHeight)
2776 {
2777 pthread_cancel (g_threadid_readimage);
2778 pthread_join (g_threadid_readimage, NULL);
2779 DBG (DBG_FUNC, "MustScanner_GetMono1BitLine1200DPI: thread exit\n");
2780
2781 *wLinesCount = TotalXferLines;
2782 g_isScanning = FALSE;
2783 return TRUE;
2784 }
2785
2786 if (GetScannedLines () > g_wtheReadyLines)
2787 {
2788 if (ST_Reflective == g_ScanType)
2789 {
2790 wLinePosEven = (g_wtheReadyLines) % g_wMaxScanLines;
2791 wLinePosOdd =
2792 (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
2793 }
2794 else
2795 {
2796 wLinePosOdd = (g_wtheReadyLines) % g_wMaxScanLines;
2797 wLinePosEven =
2798 (g_wtheReadyLines - g_wPixelDistance) % g_wMaxScanLines;
2799 }
2800
2801
2802
2803 for (i = 0; i < g_SWWidth;)
2804 {
2805 if ((i + 1) != g_SWWidth)
2806 {
2807 if (*(g_lpReadImageHead + wLinePosOdd * g_BytesPerRow + i) >
2808 g_wLineartThreshold)
2809 *(lpLine + i / 8) += (0x80 >> (i % 8));
2810 i++;
2811 if (i >= g_SWWidth)
2812 {
2813 break;
2814 }
2815
2816 if (*(g_lpReadImageHead + wLinePosEven * g_BytesPerRow + i)
2817 > g_wLineartThreshold)
2818 *(lpLine + i / 8) += (0x80 >> (i % 8));
2819 i++;
2820 }
2821 }
2822
2823 TotalXferLines++;
2824 g_dwTotalTotalXferLines++;
2825 lpLine += g_SWBytesPerRow / 8;
2826 AddReadyLines ();
2827
2828
2829 }
2830 if (g_isCanceled)
2831 {
2832 pthread_cancel (g_threadid_readimage);
2833 pthread_join (g_threadid_readimage, NULL);
2834 DBG (DBG_FUNC, "MustScanner_GetMono1BitLine1200DPI: thread exit\n");
2835
2836 break;
2837 }
2838 } /*end for */
2839
2840 *wLinesCount = TotalXferLines;
2841 g_isScanning = FALSE;
2842
2843 DBG (DBG_FUNC,
2844 "MustScanner_GetMono1BitLine1200DPI: leave MustScanner_GetMono1BitLine1200DPI\n");
2845 return TRUE;
2846 }
2847
2848 /**********************************************************************
2849 Author: Jack Date: 2005/05/21
2850 Routine Description:
2851 prepare calculate Max and Min value
2852 Parameters:
2853 wResolution: the scan resolution
2854 Return value:
2855 none
2856 ***********************************************************************/
2857 static void
MustScanner_PrepareCalculateMaxMin(unsigned short wResolution)2858 MustScanner_PrepareCalculateMaxMin (unsigned short wResolution)
2859 {
2860 g_wDarkCalWidth = 52;
2861 if (wResolution <= 600)
2862 {
2863 g_wCalWidth = ((5120 * wResolution / 600 + 511) >> 9) << 9;
2864 g_wDarkCalWidth = g_wDarkCalWidth / (1200 / wResolution);
2865
2866 if (wResolution < 200)
2867 {
2868 g_nPowerNum = 3;
2869 g_nSecLength = 8; /* 2^nPowerNum */
2870 g_nDarkSecLength = g_wDarkCalWidth / 2; /* Dark has at least 2 sections */
2871 }
2872 else
2873 {
2874 g_nPowerNum = 6;
2875 g_nSecLength = 64; /* 2^nPowerNum */
2876 g_nDarkSecLength = g_wDarkCalWidth / 3;
2877 }
2878 }
2879 else
2880 {
2881 g_nPowerNum = 6;
2882 g_nSecLength = 64; /*2^nPowerNum */
2883 g_wCalWidth = 10240;
2884 g_nDarkSecLength = g_wDarkCalWidth / 5;
2885 }
2886
2887 if (g_nDarkSecLength <= 0)
2888 {
2889 g_nDarkSecLength = 1;
2890 }
2891
2892 g_wStartPosition = 13 * wResolution / 1200;
2893 g_wCalWidth -= g_wStartPosition;
2894
2895
2896 /* start of find Max value */
2897 g_nSecNum = (int) (g_wCalWidth / g_nSecLength);
2898
2899 /* start of fin min value */
2900 g_nDarkSecNum = (int) (g_wDarkCalWidth / g_nDarkSecLength);
2901 }
2902
2903 /**********************************************************************
2904 Author: Jack Date: 2005/05/21
2905 Routine Description:
2906 calculate the Max and Min value
2907 Parameters:
2908 pBuffer: the image data
2909 lpMaxValue: the max value
2910 lpMinValue: the min value
2911 wResolution: the scan resolution
2912 Return value:
2913 none
2914 ***********************************************************************/
2915 static void
MustScanner_CalculateMaxMin(SANE_Byte * pBuffer,unsigned short * lpMaxValue,unsigned short * lpMinValue,unsigned short wResolution)2916 MustScanner_CalculateMaxMin (SANE_Byte * pBuffer, unsigned short * lpMaxValue,
2917 unsigned short * lpMinValue, unsigned short wResolution)
2918 {
2919 unsigned short *wSecData = NULL, *wDarkSecData = NULL;
2920 int i, j;
2921
2922 (void) wResolution;
2923
2924 wSecData = (unsigned short *) malloc (sizeof (unsigned short) * g_nSecNum);
2925 if (wSecData == NULL)
2926 {
2927 return;
2928 }
2929 else
2930 {
2931 memset (wSecData, 0, g_nSecNum * sizeof (unsigned short));
2932 }
2933
2934 for (i = 0; i < g_nSecNum; i++)
2935 {
2936
2937 for (j = 0; j < g_nSecLength; j++)
2938 wSecData[i] += *(pBuffer + g_wStartPosition + i * g_nSecLength + j);
2939 wSecData[i] >>= g_nPowerNum;
2940 }
2941
2942 *lpMaxValue = wSecData[0];
2943 for (i = 0; i < g_nSecNum; i++)
2944 {
2945 if (*lpMaxValue < wSecData[i])
2946 *lpMaxValue = wSecData[i];
2947 }
2948
2949 free (wSecData);
2950
2951 wDarkSecData = (unsigned short *) malloc (sizeof (unsigned short) * g_nDarkSecNum);
2952 if (wDarkSecData == NULL)
2953 {
2954 return;
2955 }
2956 else
2957 {
2958 memset (wDarkSecData, 0, g_nDarkSecNum * sizeof (unsigned short));
2959 }
2960
2961 for (i = 0; i < g_nDarkSecNum; i++)
2962 {
2963 for (j = 0; j < g_nDarkSecLength; j++)
2964 wDarkSecData[i] +=
2965 *(pBuffer + g_wStartPosition + i * g_nDarkSecLength + j);
2966
2967 wDarkSecData[i] /= g_nDarkSecLength;
2968 }
2969
2970 *lpMinValue = wDarkSecData[0];
2971 for (i = 0; i < g_nDarkSecNum; i++)
2972 {
2973 if (*lpMinValue > wDarkSecData[i])
2974 *lpMinValue = wDarkSecData[i];
2975 }
2976 free (wDarkSecData);
2977 }
2978
2979
2980 /**********************************************************************
2981 Author: Jack Date: 2005/05/15
2982 Routine Description:
2983 Read the data from scanner
2984 Parameters:
2985 none
2986 Return value:
2987 if operation is success
2988 return TRUE
2989 else
2990 return FALSE
2991 ***********************************************************************/
2992 static void *
MustScanner_ReadDataFromScanner(void * dummy)2993 MustScanner_ReadDataFromScanner (void * dummy)
2994 {
2995 unsigned short wTotalReadImageLines = 0;
2996 unsigned short wWantedLines = g_Height;
2997 SANE_Byte * lpReadImage = g_lpReadImageHead;
2998 SANE_Bool isWaitImageLineDiff = FALSE;
2999 unsigned int wMaxScanLines = g_wMaxScanLines;
3000 unsigned short wReadImageLines = 0;
3001 unsigned short wScanLinesThisBlock;
3002 unsigned short wBufferLines = g_wLineDistance * 2 + g_wPixelDistance;
3003
3004 (void) dummy;
3005 DBG (DBG_FUNC,
3006 "MustScanner_ReadDataFromScanner: call in, and in new thread\n");
3007
3008 while (wTotalReadImageLines < wWantedLines && g_lpReadImageHead)
3009 {
3010 if (!isWaitImageLineDiff)
3011 {
3012 wScanLinesThisBlock =
3013 (wWantedLines - wTotalReadImageLines) <
3014 g_wScanLinesPerBlock ? (wWantedLines -
3015 wTotalReadImageLines) :
3016 g_wScanLinesPerBlock;
3017
3018 DBG (DBG_FUNC,
3019 "MustScanner_ReadDataFromScanner: wWantedLines=%d\n",
3020 wWantedLines);
3021
3022 DBG (DBG_FUNC,
3023 "MustScanner_ReadDataFromScanner: wScanLinesThisBlock=%d\n",
3024 wScanLinesThisBlock);
3025
3026 if (SANE_STATUS_GOOD !=
3027 Asic_ReadImage (&g_chip, lpReadImage, wScanLinesThisBlock))
3028 {
3029 DBG (DBG_FUNC,
3030 "MustScanner_ReadDataFromScanner:Asic_ReadImage return error\n");
3031 DBG (DBG_FUNC, "MustScanner_ReadDataFromScanner:thread exit\n");
3032 return NULL;
3033 }
3034
3035 /*has read in memory Buffer */
3036 wReadImageLines += wScanLinesThisBlock;
3037
3038 AddScannedLines (wScanLinesThisBlock);
3039
3040 wTotalReadImageLines += wScanLinesThisBlock;
3041
3042 lpReadImage += wScanLinesThisBlock * g_BytesPerRow;
3043
3044 /*Buffer is full */
3045 if (wReadImageLines >= wMaxScanLines)
3046 {
3047 lpReadImage = g_lpReadImageHead;
3048 wReadImageLines = 0;
3049 }
3050
3051 if ((g_dwScannedTotalLines - GetReadyLines ())
3052 >= (wMaxScanLines - (wBufferLines + g_wScanLinesPerBlock))
3053 && g_dwScannedTotalLines > GetReadyLines ())
3054 {
3055 isWaitImageLineDiff = TRUE;
3056 }
3057 }
3058 else if (g_dwScannedTotalLines <=
3059 GetReadyLines () + wBufferLines + g_wScanLinesPerBlock)
3060 {
3061 isWaitImageLineDiff = FALSE;
3062 }
3063
3064 pthread_testcancel ();
3065 }
3066
3067 DBG (DBG_FUNC, "MustScanner_ReadDataFromScanner: Read image ok\n");
3068 DBG (DBG_FUNC, "MustScanner_ReadDataFromScanner: thread exit\n");
3069 DBG (DBG_FUNC,
3070 "MustScanner_ReadDataFromScanner: leave MustScanner_ReadDataFromScanner\n");
3071 return NULL;
3072 }
3073
3074 /**********************************************************************
3075 Author: Jack Date: 2005/05/26
3076 Routine Description:
3077 get the lines of scanned
3078 Parameters:
3079 none
3080 Return value:
3081 the lines of scanned
3082 ***********************************************************************/
3083 static unsigned int
GetScannedLines()3084 GetScannedLines ()
3085 {
3086 unsigned int dwScannedLines = 0;
3087
3088 pthread_mutex_lock (&g_scannedLinesMutex);
3089 dwScannedLines = g_dwScannedTotalLines;
3090 pthread_mutex_unlock (&g_scannedLinesMutex);
3091
3092 return dwScannedLines;
3093 }
3094
3095 /**********************************************************************
3096 Author: Jack Date: 2005/05/26
3097
3098 Routine Description:
3099 get lines which pass to superstratum
3100 Parameters:
3101 none
3102 Return value:
3103 the lines which pass to superstratum
3104 ***********************************************************************/
3105 static unsigned int
GetReadyLines()3106 GetReadyLines ()
3107 {
3108 unsigned int dwReadyLines = 0;
3109
3110 pthread_mutex_lock (&g_readyLinesMutex);
3111 dwReadyLines = g_wtheReadyLines;
3112 pthread_mutex_unlock (&g_readyLinesMutex);
3113
3114 return dwReadyLines;
3115 }
3116
3117 /**********************************************************************
3118 Author: Jack Date: 2005/05/26
3119 Routine Description:
3120 add the scanned total lines
3121 Parameters:
3122 wAddLines: add the lines
3123 Return value:
3124 none
3125 ***********************************************************************/
3126 static void
AddScannedLines(unsigned short wAddLines)3127 AddScannedLines (unsigned short wAddLines)
3128 {
3129 pthread_mutex_lock (&g_scannedLinesMutex);
3130
3131 g_dwScannedTotalLines += wAddLines;
3132
3133 pthread_mutex_unlock (&g_scannedLinesMutex);
3134 }
3135
3136 /**********************************************************************
3137 Author: Jack Date: 2005/05/26
3138 Routine Description:
3139 add the ready lines
3140 Parameters:
3141 none
3142 Return value:
3143 none
3144 ***********************************************************************/
3145 static void
AddReadyLines()3146 AddReadyLines ()
3147 {
3148 pthread_mutex_lock (&g_readyLinesMutex);
3149 g_wtheReadyLines++;
3150 pthread_mutex_unlock (&g_readyLinesMutex);
3151 }
3152
3153 /**********************************************************************
3154 Author: Jack Date: 2005/05/26
3155 Routine Description:
3156 modify the point
3157 Parameters:
3158 lpImageData: the data of image
3159 lpImageDataBefore: the data of before line image
3160 dwBytesPerLine: the bytes of per line
3161 dwLinesCount: the line count
3162 wPixDistance: the pixel distance
3163 wModPtCount: the modify point count
3164 Return value:
3165 none
3166 ***********************************************************************/
3167 static void
ModifyLinePoint(SANE_Byte * lpImageData,SANE_Byte * lpImageDataBefore,unsigned int dwBytesPerLine,unsigned int dwLinesCount,unsigned short wPixDistance,unsigned short wModPtCount)3168 ModifyLinePoint (SANE_Byte * lpImageData,
3169 SANE_Byte * lpImageDataBefore,
3170 unsigned int dwBytesPerLine,
3171 unsigned int dwLinesCount, unsigned short wPixDistance, unsigned short wModPtCount)
3172 {
3173 unsigned short i = 0;
3174 unsigned short j = 0;
3175 unsigned short wLines = 0;
3176 unsigned int dwWidth = dwBytesPerLine / wPixDistance;
3177 for (i = wModPtCount; i > 0; i--)
3178 {
3179 for (j = 0; j < wPixDistance; j++)
3180 {
3181 /*modify the first line */
3182 *(lpImageData + (dwWidth - i) * wPixDistance + j) =
3183 (*(lpImageData + (dwWidth - i - 1) * wPixDistance + j) +
3184 *(lpImageDataBefore + (dwWidth - i) * wPixDistance + j)) / 2;
3185 /*modify other lines */
3186 for (wLines = 1; wLines < dwLinesCount; wLines++)
3187 {
3188 unsigned int dwBytesBefor = (wLines - 1) * dwBytesPerLine;
3189 unsigned int dwBytes = wLines * dwBytesPerLine;
3190 *(lpImageData + dwBytes + (dwWidth - i) * wPixDistance + j) =
3191 (*
3192 (lpImageData + dwBytes + (dwWidth - i - 1) * wPixDistance +
3193 j) + *(lpImageData + dwBytesBefor + (dwWidth -
3194 i) * wPixDistance +
3195 j)) / 2;
3196 }
3197 }
3198 }
3199 }
3200
3201 /**********************************************************************
3202 Author: Jack Date: 2005/05/15
3203 Routine Description:
3204 Modify the image data
3205 Parameters:
3206 A: the input the image data
3207 B: the input the image data
3208 Return value:
3209 the modified data
3210 ***********************************************************************/
3211 static SANE_Byte
QBET4(SANE_Byte A,SANE_Byte B)3212 QBET4 (SANE_Byte A, SANE_Byte B)
3213 {
3214 SANE_Byte bQBET[16][16] = {
3215 {0, 0, 0, 0, 1, 1, 2, 2, 4, 4, 5, 5, 8, 8, 9, 9},
3216 {0, 0, 0, 0, 1, 1, 2, 2, 4, 4, 5, 5, 8, 8, 9, 9},
3217 {0, 0, 0, 0, 1, 1, 2, 2, 4, 4, 5, 5, 8, 8, 9, 9},
3218 {0, 0, 0, 0, 1, 1, 2, 2, 4, 4, 5, 5, 8, 8, 9, 9},
3219 {1, 1, 1, 1, 3, 3, 3, 3, 6, 6, 6, 6, 10, 10, 11, 11},
3220 {1, 1, 1, 1, 3, 3, 3, 3, 6, 6, 6, 6, 10, 10, 11, 11},
3221 {2, 2, 2, 2, 3, 3, 3, 3, 7, 7, 7, 7, 10, 10, 11, 11},
3222 {2, 2, 2, 2, 3, 3, 3, 3, 7, 7, 7, 7, 10, 10, 11, 11},
3223 {4, 4, 4, 4, 6, 6, 7, 7, 12, 12, 12, 12, 13, 13, 14, 14},
3224 {4, 4, 4, 4, 6, 6, 7, 7, 12, 12, 12, 12, 13, 13, 14, 14},
3225 {5, 5, 5, 5, 6, 6, 7, 7, 12, 12, 12, 12, 13, 13, 14, 14},
3226 {5, 5, 5, 5, 6, 6, 7, 7, 12, 12, 12, 12, 13, 13, 14, 14},
3227 {8, 8, 8, 8, 10, 10, 10, 10, 13, 13, 13, 13, 15, 15, 15, 15},
3228 {8, 8, 8, 8, 10, 10, 10, 10, 13, 13, 13, 13, 15, 15, 15, 15},
3229 {9, 9, 9, 9, 11, 11, 11, 11, 14, 14, 14, 14, 15, 15, 15, 15},
3230 {9, 9, 9, 9, 11, 11, 11, 11, 14, 14, 14, 14, 15, 15, 15, 15}
3231 };
3232
3233 A = A & 0x0f;
3234 B = B & 0x0f;
3235 return bQBET[A][B];
3236 } /* end of the file MustScanner.c */
3237