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 /* forward declarations */
47
48 static SANE_Bool Reflective_Reset (void);
49 static SANE_Bool Reflective_ScanSuggest (PTARGETIMAGE pTarget, PSUGGESTSETTING pSuggest);
50 static SANE_Bool Reflective_SetupScan (COLORMODE ColorMode, unsigned short XDpi, unsigned short YDpi,
51 SANE_Bool isInvert, unsigned short X, unsigned short Y, unsigned short Width,
52 unsigned short Height);
53 static SANE_Bool Reflective_StopScan (void);
54 static SANE_Bool Reflective_GetRows (SANE_Byte * lpBlock, unsigned short * Rows, SANE_Bool isOrderInvert);
55 static SANE_Bool Reflective_AdjustAD (void);
56 static SANE_Bool Reflective_FindTopLeft (unsigned short * lpwStartX, unsigned short * lpwStartY);
57 static SANE_Bool Reflective_LineCalibration16Bits (void);
58 static SANE_Bool Reflective_PrepareScan (void);
59
60 /*function description*/
61
62 /**********************************************************************
63 Author: Jack Date: 2005/05/13
64 Routine Description:
65 reset the scanner status
66 Parameters:
67 none
68 Return value:
69 if operation is success
70 return TRUE
71 els
72 return FALSE
73 ***********************************************************************/
74 static SANE_Bool
Reflective_Reset()75 Reflective_Reset ()
76 {
77 DBG (DBG_FUNC, "Reflective_Reset: call in\n");
78
79 if (g_bOpened)
80 {
81 DBG (DBG_FUNC, "Reflective_Reset: scanner has been opened\n");
82 return FALSE;
83 }
84
85 if (SANE_STATUS_GOOD != Asic_Open (&g_chip, g_pDeviceFile))
86 {
87 DBG (DBG_FUNC, "Reflective_Reset: Asic_Open return error\n");
88 return FALSE;
89 }
90
91 if (SANE_STATUS_GOOD != Asic_Reset (&g_chip))
92 {
93 DBG (DBG_FUNC, "Reflective_Reset: Asic_Reset return error\n");
94 return FALSE;
95 }
96
97 if (SANE_STATUS_GOOD != Asic_SetSource (&g_chip, LS_REFLECTIVE))
98 {
99 DBG (DBG_FUNC, "Reflective_Reset: Asic_SetSource return error\n");
100 return FALSE;
101 }
102
103 if (SANE_STATUS_GOOD != Asic_TurnLamp (&g_chip, TRUE))
104 {
105 DBG (DBG_FUNC, "Reflective_Reset: Asic_TurnLamp return error\n");
106 return FALSE;
107 }
108
109 if (SANE_STATUS_GOOD != Asic_Close (&g_chip))
110 {
111 DBG (DBG_FUNC, "Reflective_Reset: Asic_Close return error\n");
112 return FALSE;
113 }
114
115 g_Y = 0;
116 g_X = 0;
117 g_Width = 0;
118 g_SWWidth = 0;
119 g_Height = 0;
120 g_SWHeight = 0;
121
122 g_wLineartThreshold = 128;
123 g_dwTotalTotalXferLines = 0;
124 g_bFirstReadImage = TRUE;
125
126 g_pGammaTable = NULL;
127
128 if (NULL != g_pDeviceFile)
129 {
130 free (g_pDeviceFile);
131 g_pDeviceFile = NULL;
132 }
133
134 DBG (DBG_FUNC, "Reflective_Reset: exit\n");
135
136 return TRUE;
137 }
138
139 /**********************************************************************
140 Author: Jack Date: 2005/05/13
141 Routine Description:
142 get the suggest parameter of scanning
143 Parameters:
144 pTarget: the information of scanning
145 pSuggest: suggest parameter of scanning
146 Return value:
147 if the operation is success
148 return TRUE
149 els
150 return FALSE
151 ***********************************************************************/
152 static SANE_Bool
Reflective_ScanSuggest(PTARGETIMAGE pTarget,PSUGGESTSETTING pSuggest)153 Reflective_ScanSuggest (PTARGETIMAGE pTarget, PSUGGESTSETTING pSuggest)
154 {
155 int i;
156 unsigned short wMaxWidth, wMaxHeight;
157
158 DBG (DBG_FUNC, "Reflective_ScanSuggest: call in\n");
159
160 if (NULL == pTarget || NULL == pSuggest)
161 {
162 DBG (DBG_FUNC, "Reflective_ScanSuggest: parameters error\n");
163 return FALSE;
164 }
165
166 /*1. Looking up Optical Y Resolution */
167 for (i = 0; s_wOpticalYDpi[i] != 0; i++)
168 {
169 if (s_wOpticalYDpi[i] <= pTarget->wDpi)
170 {
171 pSuggest->wYDpi = s_wOpticalYDpi[i];
172 break;
173 }
174 }
175 if (s_wOpticalYDpi[i] == 0)
176 {
177 i--;
178 pSuggest->wYDpi = s_wOpticalYDpi[i];
179 }
180
181 /*2. Looking up Optical X Resolution */
182 for (i = 0; s_wOpticalXDpi[i] != 0; i++)
183 {
184 if (s_wOpticalXDpi[i] <= pTarget->wDpi)
185 {
186 pSuggest->wXDpi = s_wOpticalXDpi[i];
187 break;
188 }
189 }
190 if (s_wOpticalXDpi[i] == 0)
191 {
192 i--;
193 pSuggest->wXDpi = s_wOpticalXDpi[i];
194 }
195
196 DBG (DBG_FUNC, "Reflective_ScanSuggest: pTarget->wDpi = %d\n",
197 pTarget->wDpi);
198 DBG (DBG_FUNC, "Reflective_ScanSuggest: pSuggest->wXDpi = %d\n",
199 pSuggest->wXDpi);
200
201
202
203
204
205
206
207 DBG (DBG_FUNC, "Reflective_ScanSuggest: pSuggest->wYDpi = %d\n",
208 pSuggest->wYDpi);
209
210 /*3. suggest scan area */
211 pSuggest->wX =
212 (unsigned short) (((unsigned int) (pTarget->wX) * (unsigned int) (pSuggest->wXDpi)) /
213 (unsigned int) (pTarget->wDpi));
214 pSuggest->wY =
215 (unsigned short) (((unsigned int) (pTarget->wY) * (unsigned int) (pSuggest->wYDpi)) /
216 (unsigned int) (pTarget->wDpi));
217 pSuggest->wWidth =
218 (unsigned short) (((unsigned int) (pTarget->wWidth) * (unsigned int) (pSuggest->wXDpi)) /
219 (unsigned int) (pTarget->wDpi));
220 pSuggest->wHeight =
221 (unsigned short) (((unsigned int) (pTarget->wHeight) * (unsigned int) (pSuggest->wYDpi)) /
222 (unsigned int) (pTarget->wDpi));
223
224 pSuggest->wWidth = (pSuggest->wWidth / 2) * 2;
225
226 DBG (DBG_FUNC, "Reflective_ScanSuggest: pTarget->wX = %d\n", pTarget->wX);
227 DBG (DBG_FUNC, "Reflective_ScanSuggest: pTarget->wY = %d\n", pTarget->wY);
228 DBG (DBG_FUNC, "Reflective_ScanSuggest: pTarget->wWidth = %d\n",
229 pTarget->wWidth);
230 DBG (DBG_FUNC, "Reflective_ScanSuggest: pTarget->wHeight = %d\n",
231 pTarget->wHeight);
232
233 DBG (DBG_FUNC, "Reflective_ScanSuggest: pSuggest->wX = %d\n", pSuggest->wX);
234 DBG (DBG_FUNC, "Reflective_ScanSuggest: pSuggest->wY = %d\n", pSuggest->wY);
235 DBG (DBG_FUNC, "Reflective_ScanSuggest: pSuggest->wWidth = %d\n",
236 pSuggest->wWidth);
237 DBG (DBG_FUNC, "Reflective_ScanSuggest: pSuggest->wHeight = %d\n",
238 pSuggest->wHeight);
239
240 if (pTarget->cmColorMode == CM_TEXT)
241 {
242 pSuggest->wWidth = ((pSuggest->wWidth + 7) >> 3) << 3;
243 if (pSuggest->wWidth < 8)
244 pSuggest->wWidth = 8;
245 }
246
247 /*4. check width and height */
248 wMaxWidth = (MAX_SCANNING_WIDTH * pSuggest->wXDpi) / 300;
249 wMaxHeight = (3480 * pSuggest->wYDpi) / 300; /* 3480 for bumping */
250
251 DBG (DBG_FUNC, "Reflective_ScanSuggest: wMaxWidth = %d\n", wMaxWidth);
252 DBG (DBG_FUNC, "Reflective_ScanSuggest: wMaxHeight = %d\n", wMaxHeight);
253
254 if (CM_TEXT == pTarget->cmColorMode)
255 {
256 wMaxWidth = (wMaxWidth >> 3) << 3;
257 }
258 if (pSuggest->wWidth > wMaxWidth)
259 {
260 pSuggest->wWidth = wMaxWidth;
261 }
262
263
264 if (pSuggest->wHeight > wMaxHeight)
265 {
266 pSuggest->wHeight = wMaxHeight;
267 }
268
269 DBG (DBG_FUNC, "Reflective_ScanSuggest: g_Width=%d\n", g_Width);
270
271 g_Width = ((pSuggest->wWidth + 15) >> 4) << 4; /*Real Scan Width */
272
273 DBG (DBG_FUNC, "Reflective_ScanSuggest: again, g_Width=%d\n", g_Width);
274
275 g_Height = pSuggest->wHeight;
276
277 if (pTarget->isOptimalSpeed)
278 {
279 switch (pTarget->cmColorMode)
280 {
281 case CM_RGB48:
282 pSuggest->cmScanMode = CM_RGB48;
283 pSuggest->dwBytesPerRow = (unsigned int) ((pSuggest->wWidth) * 6);
284 break;
285 case CM_RGB24:
286 pSuggest->cmScanMode = CM_RGB24ext;
287 pSuggest->dwBytesPerRow = (unsigned int) ((pSuggest->wWidth) * 3);
288 break;
289 case CM_GRAY16:
290 pSuggest->cmScanMode = CM_GRAY16ext;
291 pSuggest->dwBytesPerRow = (unsigned int) ((pSuggest->wWidth) * 2);
292 break;
293 case CM_GRAY8:
294 pSuggest->cmScanMode = CM_GRAY8ext;
295 pSuggest->dwBytesPerRow = (unsigned int) ((pSuggest->wWidth));
296 break;
297 case CM_TEXT:
298 pSuggest->cmScanMode = CM_TEXT;
299 pSuggest->dwBytesPerRow = (unsigned int) (pSuggest->wWidth) / 8;
300 break;
301 default:
302 break;
303 }
304 }
305 else
306 {
307 switch (pTarget->cmColorMode)
308 {
309 case CM_RGB48:
310 pSuggest->cmScanMode = CM_RGB48;
311 pSuggest->dwBytesPerRow = (unsigned int) ((pSuggest->wWidth) * 6);
312 break;
313 case CM_RGB24:
314 pSuggest->cmScanMode = CM_RGB24ext;
315 pSuggest->dwBytesPerRow = (unsigned int) ((pSuggest->wWidth) * 3);
316 break;
317 case CM_GRAY16:
318 pSuggest->cmScanMode = CM_GRAY16ext;
319 pSuggest->dwBytesPerRow = (unsigned int) ((pSuggest->wWidth) * 2);
320 break;
321 case CM_GRAY8:
322 pSuggest->cmScanMode = CM_GRAY8ext;
323 pSuggest->dwBytesPerRow = (unsigned int) ((pSuggest->wWidth));
324 break;
325 case CM_TEXT:
326 pSuggest->cmScanMode = CM_TEXT;
327 pSuggest->dwBytesPerRow = (unsigned int) (pSuggest->wWidth) / 8;
328 break;
329 default:
330 break;
331 }
332 }
333
334 DBG (DBG_FUNC, "Reflective_ScanSuggest: pSuggest->dwBytesPerRow = %d\n",
335 pSuggest->dwBytesPerRow);
336 DBG (DBG_FUNC, "Reflective_ScanSuggest: leave Reflective_ScanSuggest\n");
337 return TRUE;
338 }
339
340 /**********************************************************************
341 Author: Jack Date: 2005/05/13
342 Routine Description:
343 setup scanning process
344 Parameters:
345 ColorMode: ScanMode of Scanning, CM_RGB48, CM_GRAY and so on
346 XDpi: X Resolution
347 YDpi: Y Resolution
348 isInvert: the RGB order
349 X: X start coordinate
350 Y: Y start coordinate
351 Width: Width of Scan Image
352 Height: Height of Scan Image
353 Return value:
354 if the operation is success
355 return TRUE
356 else
357 return FALSE
358 ***********************************************************************/
359 static SANE_Bool
Reflective_SetupScan(COLORMODE ColorMode,unsigned short XDpi,unsigned short YDpi,SANE_Bool isInvert,unsigned short X,unsigned short Y,unsigned short Width,unsigned short Height)360 Reflective_SetupScan (COLORMODE ColorMode,
361 unsigned short XDpi,
362 unsigned short YDpi,
363 SANE_Bool isInvert, unsigned short X, unsigned short Y, unsigned short Width, unsigned short Height)
364 {
365 (void) isInvert;
366 DBG (DBG_FUNC, "Reflective_SetupScan: Call in\n");
367 if (g_bOpened)
368 {
369 DBG (DBG_FUNC, "Reflective_SetupScan: scanner has been opened\n");
370 return FALSE;
371 }
372 if (!g_bPrepared)
373 {
374 DBG (DBG_FUNC, "Reflective_SetupScan: scanner not prepared\n");
375 return FALSE;
376 }
377
378 g_ScanMode = ColorMode;
379 g_XDpi = XDpi;
380 g_YDpi = YDpi;
381 g_SWWidth = Width;
382 g_SWHeight = Height;
383
384 switch (g_YDpi)
385 {
386 case 1200:
387 g_wPixelDistance = 4; /*even & odd sensor problem */
388 g_wLineDistance = 24;
389 g_Height += g_wPixelDistance;
390 break;
391 case 600:
392 g_wPixelDistance = 0; /*no even & odd problem */
393 g_wLineDistance = 12;
394 break;
395 case 300:
396 g_wPixelDistance = 0;
397 g_wLineDistance = 6;
398 break;
399 case 150:
400 g_wPixelDistance = 0;
401 g_wLineDistance = 3;
402 break;
403
404 case 75:
405 case 50:
406 g_wPixelDistance = 0;
407 g_wLineDistance = 1;
408 break;
409 default:
410 g_wLineDistance = 0;
411 }
412
413 switch (g_ScanMode)
414 {
415 case CM_RGB48:
416 g_BytesPerRow = 6 * g_Width;
417 g_SWBytesPerRow = 6 * g_SWWidth;
418 g_bScanBits = 48;
419 g_Height += g_wLineDistance * 2; /*add height to do line distance */
420 break;
421 case CM_RGB24ext:
422 g_BytesPerRow = 3 * g_Width;
423 g_SWBytesPerRow = 3 * g_SWWidth;
424 g_bScanBits = 24;
425 g_Height += g_wLineDistance * 2; /*add height to do line distance */
426 break;
427 case CM_GRAY16ext:
428 g_BytesPerRow = 2 * g_Width;
429 g_SWBytesPerRow = 2 * g_SWWidth;
430 g_bScanBits = 16;
431 break;
432 case CM_GRAY8ext:
433 case CM_TEXT:
434 g_BytesPerRow = g_Width;
435 g_SWBytesPerRow = g_SWWidth;
436 g_bScanBits = 8;
437 break;
438 default:
439 break;
440 }
441
442 if (Asic_Open (&g_chip, g_pDeviceFile) != SANE_STATUS_GOOD)
443 {
444 DBG (DBG_FUNC, "Reflective_SetupScan: Asic_Open return error\n");
445 return FALSE;
446 }
447
448 DBG (DBG_FUNC, "Reflective_SetupScan: Asic_Open successfully\n");
449
450 g_bOpened = TRUE;
451
452 Asic_TurnLamp (&g_chip, FALSE);
453 Asic_TurnTA (&g_chip, FALSE);
454 Asic_TurnLamp (&g_chip, TRUE);
455
456 if (1200 == g_XDpi)
457 {
458 g_XDpi = 600;
459
460 if (Reflective_AdjustAD () == FALSE)
461 {
462
463 DBG (DBG_FUNC,
464 "Reflective_SetupScan: Reflective_AdjustAD return error\n");
465 return FALSE;
466 }
467 DBG (DBG_FUNC,
468 "Reflective_SetupScan: Reflective_AdjustAD successfully\n");
469
470 if (Reflective_FindTopLeft (&g_X, &g_Y) == FALSE)
471 {
472 g_X = 187;
473 g_Y = 43;
474 }
475
476 g_XDpi = 1200;
477
478 if (Reflective_AdjustAD () == FALSE)
479 {
480 DBG (DBG_FUNC,
481 "Reflective_SetupScan: Reflective_AdjustAD return error\n");
482 return FALSE;
483 }
484 DBG (DBG_FUNC,
485 "Reflective_SetupScan: Reflective_AdjustAD successfully\n");
486 }
487 else
488 {
489 if (Reflective_AdjustAD () == FALSE)
490 {
491 DBG (DBG_FUNC,
492 "Reflective_SetupScan: Reflective_AdjustAD return error\n");
493 return FALSE;
494 }
495 DBG (DBG_FUNC,
496 "Reflective_SetupScan: Reflective_AdjustAD successfully\n");
497 if (Reflective_FindTopLeft (&g_X, &g_Y) == FALSE)
498 {
499 g_X = 187;
500 g_Y = 43;
501 }
502 }
503
504
505 DBG (DBG_FUNC, "after find top left,g_X=%d,g_Y=%d\n", g_X, g_Y);
506
507 if (1200 == g_XDpi)
508 {
509 g_X =
510 g_X * 1200 / FIND_LEFT_TOP_CALIBRATE_RESOLUTION + X * 1200 / g_XDpi +
511 47;
512
513 }
514 else
515 {
516 if (75 == g_XDpi)
517 {
518 g_X = g_X + X * 600 / g_XDpi;
519 }
520 else
521 {
522 g_X = g_X + X * 600 / g_XDpi + 23;
523 }
524 }
525
526 g_Y =
527 g_Y * 1200 / FIND_LEFT_TOP_CALIBRATE_RESOLUTION + Y * 1200 / g_YDpi + 47;
528
529
530 DBG (DBG_FUNC, "before line calibration,g_X=%d,g_Y=%d\n", g_X, g_Y);
531
532 if (Reflective_LineCalibration16Bits () == FALSE)
533 {
534 DBG (DBG_FUNC,
535 "Reflective_SetupScan: Reflective_LineCalibration16Bits return error\n");
536 return FALSE;
537 }
538
539 DBG (DBG_FUNC,
540 "Reflective_SetupScan: after Reflective_LineCalibration16Bits,g_X=%d,g_Y=%d\n",
541 g_X, g_Y);
542
543 DBG (DBG_FUNC, "Reflective_SetupScan: before Asic_SetWindow\n");
544
545 DBG (DBG_FUNC,
546 "Reflective_SetupScan: g_bScanBits=%d, g_XDpi=%d, g_YDpi=%d, g_X=%d, g_Y=%d, g_Width=%d, g_Height=%d\n",
547 g_bScanBits, g_XDpi, g_YDpi, g_X, g_Y, g_Width, g_Height);
548
549 if (g_Y > 300)
550 {
551 Asic_MotorMove (&g_chip, TRUE, g_Y - 300);
552 }
553 else
554 {
555 Asic_MotorMove (&g_chip, FALSE, 300 - g_Y);
556 }
557 g_Y = 300;
558
559 Asic_SetWindow (&g_chip, g_bScanBits, g_XDpi, g_YDpi, g_X, g_Y, g_Width,
560 g_Height);
561
562 DBG (DBG_FUNC, "Reflective_SetupScan: leave Reflective_SetupScan\n");
563 return Reflective_PrepareScan ();
564 }
565
566 /**********************************************************************
567 Author: Jack Date: 2005/05/13
568 Routine Description:
569 To adjust the value of offset gain of R/G/B
570 Parameters:
571 none
572 Return value:
573 if operation is success
574 return TRUE
575 else
576 return FALSE
577 ***********************************************************************/
578 static SANE_Bool
Reflective_AdjustAD()579 Reflective_AdjustAD ()
580 {
581 SANE_Byte * lpCalData;
582 unsigned short wCalWidth;
583 int nTimesOfCal;
584 unsigned short wMaxValueR, wMinValueR, wMaxValueG, wMinValueG, wMaxValueB, wMinValueB;
585 #if 0
586 SANE_Byte bDarkMaxLevel;
587 SANE_Byte bDarkMinLevel;
588 SANE_Byte bLastMinR, bLastROffset, bROffsetUpperBound = 255, bROffsetLowerBound =
589 0;
590 SANE_Byte bLastMinG, bLastGOffset, bGOffsetUpperBound = 255, bGOffsetLowerBound =
591 0;
592 SANE_Byte bLastMinB, bLastBOffset, bBOffsetUpperBound = 255, bBOffsetLowerBound =
593 0;
594 float fRFactor = 1.0;
595 float fGFactor = 1.0;
596 float fBFactor = 1.0;
597 #endif
598 unsigned short wAdjustADResolution;
599
600 DBG (DBG_FUNC, "Reflective_AdjustAD: call in\n");
601 if (!g_bOpened)
602 {
603 DBG (DBG_FUNC, "Reflective_AdjustAD: scanner has been opened\n");
604 return FALSE;
605 }
606 if (!g_bPrepared)
607 {
608 DBG (DBG_FUNC, "Reflective_AdjustAD: scanner not prepared\n");
609 return FALSE;
610 }
611
612
613 g_chip.AD.DirectionR = R_DIRECTION;
614 g_chip.AD.DirectionG = G_DIRECTION;
615 g_chip.AD.DirectionB = B_DIRECTION;
616 g_chip.AD.GainR = R_GAIN;
617 g_chip.AD.GainG = G_GAIN;
618 g_chip.AD.GainB = B_GAIN;
619 g_chip.AD.OffsetR = 152;
620 g_chip.AD.OffsetG = 56;
621 g_chip.AD.OffsetB = 8;
622
623 if (g_XDpi <= 600)
624 {
625 wAdjustADResolution = 600;
626 }
627 else
628 {
629 wAdjustADResolution = 1200;
630 }
631 wCalWidth = 10240;
632
633 lpCalData = (SANE_Byte *) malloc (sizeof (SANE_Byte) * wCalWidth * 3);
634 if (lpCalData == NULL)
635 {
636 DBG (DBG_FUNC, "Reflective_AdjustAD: lpCalData malloc error\n");
637 return FALSE;
638 }
639
640 Asic_SetMotorType (&g_chip, FALSE, TRUE);
641
642 Asic_SetCalibrate (&g_chip, 24, wAdjustADResolution, wAdjustADResolution, 0,
643 0, wCalWidth, 1, FALSE);
644 MustScanner_PrepareCalculateMaxMin (wAdjustADResolution);
645 nTimesOfCal = 0;
646
647 #ifdef DEBUG_SAVE_IMAGE
648 Asic_SetAFEGainOffset (&g_chip);
649 Asic_ScanStart (&g_chip);
650 Asic_ReadCalibrationData (&g_chip, lpCalData, wCalWidth * 3, 24);
651 Asic_ScanStop (&g_chip);
652
653 FILE *stream = NULL;
654 SANE_Byte * lpBuf = (SANE_Byte *) malloc (50);
655 if (NULL == lpBuf)
656 {
657 return FALSE;
658 }
659 memset (lpBuf, 0, 50);
660
661 stream = fopen ("/root/AD(Ref).pnm\n", "wb+\n");
662 sprintf (lpBuf, "P6\n%d %d\n255\n\n", wCalWidth, 1);
663 fwrite (lpBuf, sizeof (SANE_Byte), strlen (lpBuf), stream);
664 fwrite (lpCalData, sizeof (SANE_Byte), wCalWidth * 3, stream);
665 fclose (stream);
666 free (lpBuf);
667 #endif
668
669 do
670 {
671 DBG (DBG_FUNC,
672 "Reflective_AdjustAD: run in first adjust offset do-while\n");
673 Asic_SetAFEGainOffset (&g_chip);
674 Asic_ScanStart (&g_chip);
675 Asic_ReadCalibrationData (&g_chip, lpCalData, wCalWidth * 3, 24);
676 Asic_ScanStop (&g_chip);
677
678 MustScanner_CalculateMaxMin (lpCalData, &wMaxValueR, &wMinValueR,
679 wAdjustADResolution);
680 MustScanner_CalculateMaxMin (lpCalData + wCalWidth, &wMaxValueG,
681 &wMinValueG, wAdjustADResolution);
682 MustScanner_CalculateMaxMin (lpCalData + wCalWidth * 2, &wMaxValueB,
683 &wMinValueB, wAdjustADResolution);
684
685 if (g_chip.AD.DirectionR == 0)
686 {
687 if (wMinValueR > 15)
688 {
689 if (g_chip.AD.OffsetR < 8)
690 g_chip.AD.DirectionR = 1;
691 else
692 g_chip.AD.OffsetR -= 8;
693 }
694 else if (wMinValueR < 5)
695 g_chip.AD.OffsetR += 8;
696 }
697 else
698 {
699 if (wMinValueR > 15)
700 g_chip.AD.OffsetR += 8;
701 else if (wMinValueR < 5)
702 g_chip.AD.OffsetR -= 8;
703 }
704
705 if (g_chip.AD.DirectionG == 0)
706 {
707 if (wMinValueG > 15)
708 {
709 if (g_chip.AD.OffsetG < 8)
710 g_chip.AD.DirectionG = 1;
711 else
712 g_chip.AD.OffsetG -= 8;
713 }
714 else if (wMinValueG < 5)
715 g_chip.AD.OffsetG += 8;
716 }
717 else
718 {
719 if (wMinValueG > 15)
720 g_chip.AD.OffsetG += 8;
721 else if (wMinValueG < 5)
722 g_chip.AD.OffsetG -= 8;
723 }
724
725 if (g_chip.AD.DirectionB == 0)
726 {
727 if (wMinValueB > 15)
728 {
729 if (g_chip.AD.OffsetB < 8)
730 g_chip.AD.DirectionB = 1;
731 else
732 g_chip.AD.OffsetB -= 8;
733 }
734
735 else if (wMinValueB < 5)
736 g_chip.AD.OffsetB += 8;
737 }
738 else
739 {
740 if (wMinValueB > 15)
741 g_chip.AD.OffsetB += 8;
742 else if (wMinValueB < 5)
743 g_chip.AD.OffsetB -= 8;
744 }
745
746 nTimesOfCal++;
747 if (nTimesOfCal > 10)
748 break;
749 }
750 while (wMinValueR > 15 || wMinValueR < 5
751 || wMinValueG > 15 || wMinValueG < 5
752 || wMinValueB > 15 || wMinValueB < 5);
753
754 DBG (DBG_FUNC,
755 "Reflective_AdjustAD: run out first adjust offset do-while\n");
756
757 DBG (DBG_FUNC, "Reflective_AdjustAD: \
758 g_chip.AD.OffsetR=%d,\
759 g_chip.AD.OffsetG=%d,\
760 g_chip.AD.OffsetB=%d\n", g_chip.AD.OffsetR, g_chip.AD.OffsetG, g_chip.AD.OffsetB);
761
762 g_chip.AD.GainR = 1 - (double) (wMaxValueR - wMinValueR) / 210 > 0 ?
763 (SANE_Byte) (((1 -
764 (double) (wMaxValueR - wMinValueR) / 210)) * 63 * 6 / 5) : 0;
765 g_chip.AD.GainG =
766 1 - (double) (wMaxValueG - wMinValueG) / 210 >
767 0 ? (SANE_Byte) (((1 - (double) (wMaxValueG - wMinValueG) / 210)) * 63 * 6 /
768 5) : 0;
769 g_chip.AD.GainB =
770 1 - (double) (wMaxValueB - wMinValueB) / 210 >
771 0 ? (SANE_Byte) (((1 - (double) (wMaxValueB - wMinValueB) / 210)) * 63 * 6 /
772 5) : 0;
773
774 if (g_chip.AD.GainR > 63)
775 g_chip.AD.GainR = 63;
776 if (g_chip.AD.GainG > 63)
777 g_chip.AD.GainG = 63;
778 if (g_chip.AD.GainB > 63)
779 g_chip.AD.GainB = 63;
780
781 DBG (DBG_FUNC, "Reflective_AdjustAD: "
782 "g_chip.AD.GainR = %d,"
783 "g_chip.AD.GainG = %d,"
784 "g_chip.AD.GainB = %d\n",
785 g_chip.AD.GainR, g_chip.AD.GainG, g_chip.AD.GainB);
786
787 nTimesOfCal = 0;
788 do
789 {
790 Asic_SetAFEGainOffset (&g_chip);
791 Asic_ScanStart (&g_chip);
792 Asic_ReadCalibrationData (&g_chip, lpCalData, wCalWidth * 3, 24);
793 Asic_ScanStop (&g_chip);
794
795 MustScanner_CalculateMaxMin (lpCalData, &wMaxValueR, &wMinValueR,
796 wAdjustADResolution);
797 MustScanner_CalculateMaxMin (lpCalData + wCalWidth, &wMaxValueG,
798 &wMinValueG, wAdjustADResolution);
799 MustScanner_CalculateMaxMin (lpCalData + wCalWidth * 2, &wMaxValueB,
800 &wMinValueB, wAdjustADResolution);
801
802 DBG (DBG_FUNC, "Reflective_AdjustAD: "
803 "RGain=%d, ROffset=%d, RDir=%d GGain=%d, GOffset=%d, GDir=%d BGain=%d, BOffset=%d, BDir=%d\n",
804 g_chip.AD.GainR, g_chip.AD.OffsetR, g_chip.AD.DirectionR,
805 g_chip.AD.GainG, g_chip.AD.OffsetG, g_chip.AD.DirectionG,
806 g_chip.AD.GainB, g_chip.AD.OffsetB, g_chip.AD.DirectionB);
807
808 DBG (DBG_FUNC, "Reflective_AdjustAD: "
809 "MaxR=%d, MinR=%d MaxG=%d, MinG=%d MaxB=%d, MinB=%d\n",
810 wMaxValueR, wMinValueR, wMaxValueG, wMinValueG, wMaxValueB,
811 wMinValueB);
812
813 /*R Channel */
814 if ((wMaxValueR - wMinValueR) > REFL_MAX_LEVEL_RANGE)
815 {
816 if (g_chip.AD.GainR > 0)
817 g_chip.AD.GainR--;
818 }
819 else
820 {
821 if ((wMaxValueR - wMinValueR) < REFL_MIN_LEVEL_RANGE)
822 {
823 if (wMaxValueR < REFL_WHITE_MIN_LEVEL)
824 {
825 g_chip.AD.GainR++;
826 if (g_chip.AD.GainR > 63)
827 g_chip.AD.GainR = 63;
828 }
829 else
830 {
831 if (wMaxValueR > REFL_WHITE_MAX_LEVEL)
832 {
833 if (g_chip.AD.GainR < 1)
834 g_chip.AD.GainR = 0;
835 else
836 g_chip.AD.GainR--;
837 }
838 else
839 {
840 if (g_chip.AD.GainR > 63)
841 g_chip.AD.GainR = 63;
842 else
843 g_chip.AD.GainR++;
844 }
845 }
846 }
847 else
848 {
849 if (wMaxValueR > REFL_WHITE_MAX_LEVEL)
850 {
851 if (g_chip.AD.GainR < 1)
852 g_chip.AD.GainR = 0;
853 else
854 g_chip.AD.GainR--;
855 }
856
857 if (wMaxValueR < REFL_WHITE_MIN_LEVEL)
858 {
859 if (g_chip.AD.GainR > 63)
860 g_chip.AD.GainR = 63;
861 else
862 g_chip.AD.GainR++;
863 }
864 }
865 }
866
867 /*G Channel */
868 if ((wMaxValueG - wMinValueG) > REFL_MAX_LEVEL_RANGE)
869 {
870 if (g_chip.AD.GainG > 0)
871 g_chip.AD.GainG--;
872 }
873 else
874 {
875 if ((wMaxValueG - wMinValueG) < REFL_MIN_LEVEL_RANGE)
876 {
877 if (wMaxValueG < REFL_WHITE_MIN_LEVEL)
878 {
879 g_chip.AD.GainG++;
880 if (g_chip.AD.GainG > 63)
881 g_chip.AD.GainG = 63;
882 }
883 else
884 {
885 if (wMaxValueG > REFL_WHITE_MAX_LEVEL)
886 {
887 if (g_chip.AD.GainG < 1)
888 g_chip.AD.GainG = 0;
889 else
890 g_chip.AD.GainG--;
891 }
892 else
893 {
894 if (g_chip.AD.GainG > 63)
895 g_chip.AD.GainG = 63;
896 else
897 g_chip.AD.GainG++;
898 }
899 }
900 }
901 else
902 {
903 if (wMaxValueG > REFL_WHITE_MAX_LEVEL)
904 {
905 if (g_chip.AD.GainG < 1)
906 g_chip.AD.GainG = 0;
907 else
908 g_chip.AD.GainG--;
909 }
910
911 if (wMaxValueG < REFL_WHITE_MIN_LEVEL)
912 {
913 if (g_chip.AD.GainG > 63)
914 g_chip.AD.GainG = 63;
915 else
916 g_chip.AD.GainG++;
917 }
918 }
919 }
920
921 /* B Channel */
922 if ((wMaxValueB - wMinValueB) > REFL_MAX_LEVEL_RANGE)
923 {
924 if (g_chip.AD.GainB > 0)
925 g_chip.AD.GainB--;
926 }
927 else
928 {
929 if ((wMaxValueB - wMinValueB) < REFL_MIN_LEVEL_RANGE)
930 {
931 if (wMaxValueB < REFL_WHITE_MIN_LEVEL)
932 {
933 g_chip.AD.GainB++;
934 if (g_chip.AD.GainB > 63)
935 g_chip.AD.GainB = 63;
936 }
937 else
938 {
939 if (wMaxValueB > REFL_WHITE_MAX_LEVEL)
940 {
941 if (g_chip.AD.GainB < 1)
942 g_chip.AD.GainB = 0;
943 else
944 g_chip.AD.GainB--;
945 }
946 else
947 {
948 if (g_chip.AD.GainB > 63)
949 g_chip.AD.GainB = 63;
950 else
951 g_chip.AD.GainB++;
952 }
953 }
954 }
955 else
956 {
957 if (wMaxValueB > REFL_WHITE_MAX_LEVEL)
958
959 {
960 if (g_chip.AD.GainB < 1)
961 g_chip.AD.GainB = 0;
962 else
963 g_chip.AD.GainB--;
964 }
965
966 if (wMaxValueB < REFL_WHITE_MIN_LEVEL)
967 {
968 if (g_chip.AD.GainB > 63)
969 g_chip.AD.GainB = 63;
970 else
971 g_chip.AD.GainB++;
972 }
973 }
974 }
975 nTimesOfCal++;
976 if (nTimesOfCal > 10)
977 break;
978 }
979 while ((wMaxValueR - wMinValueR) > REFL_MAX_LEVEL_RANGE
980 || (wMaxValueR - wMinValueR) < REFL_MIN_LEVEL_RANGE
981 || (wMaxValueG - wMinValueG) > REFL_MAX_LEVEL_RANGE
982 || (wMaxValueG - wMinValueG) < REFL_MIN_LEVEL_RANGE
983 || (wMaxValueB - wMinValueB) > REFL_MAX_LEVEL_RANGE
984 || (wMaxValueB - wMinValueB) < REFL_MIN_LEVEL_RANGE);
985
986 /* Adjust Offset 2nd */
987 nTimesOfCal = 0;
988 do
989 {
990 DBG (DBG_FUNC,
991 "Reflective_AdjustAD: run in second adjust offset do-while\n");
992 Asic_SetAFEGainOffset (&g_chip);
993 Asic_ScanStart (&g_chip);
994 Asic_ReadCalibrationData (&g_chip, lpCalData, wCalWidth * 3, 24);
995 Asic_ScanStop (&g_chip);
996
997 MustScanner_CalculateMaxMin (lpCalData, &wMaxValueR, &wMinValueR,
998 wAdjustADResolution);
999 MustScanner_CalculateMaxMin (lpCalData + wCalWidth, &wMaxValueG,
1000 &wMinValueG, wAdjustADResolution);
1001 MustScanner_CalculateMaxMin (lpCalData + wCalWidth * 2, &wMaxValueB,
1002 &wMinValueB, wAdjustADResolution);
1003
1004 DBG (DBG_FUNC, "Reflective_AdjustAD: "
1005 "RGain=%d, ROffset=%d, RDir=%d GGain=%d, GOffset=%d, GDir=%d BGain=%d, BOffset=%d, BDir=%d\n",
1006 g_chip.AD.GainR, g_chip.AD.OffsetR, g_chip.AD.DirectionR,
1007 g_chip.AD.GainG, g_chip.AD.OffsetG, g_chip.AD.DirectionG,
1008 g_chip.AD.GainB, g_chip.AD.OffsetB, g_chip.AD.DirectionB);
1009
1010 DBG (DBG_FUNC, "Reflective_AdjustAD: "
1011 "MaxR=%d, MinR=%d MaxG=%d, MinG=%d MaxB=%d, MinB=%d\n",
1012 wMaxValueR, wMinValueR, wMaxValueG, wMinValueG, wMaxValueB,
1013 wMinValueB);
1014
1015 if (g_chip.AD.DirectionR == 0)
1016 {
1017 if (wMinValueR > 20)
1018 {
1019 if (g_chip.AD.OffsetR < 8)
1020 g_chip.AD.DirectionR = 1;
1021 else
1022 g_chip.AD.OffsetR -= 8;
1023 }
1024
1025 else if (wMinValueR < 10)
1026 g_chip.AD.OffsetR += 8;
1027 }
1028 else
1029 {
1030 if (wMinValueR > 20)
1031 g_chip.AD.OffsetR += 8;
1032 else if (wMinValueR < 10)
1033 g_chip.AD.OffsetR -= 8;
1034 }
1035
1036 if (g_chip.AD.DirectionG == 0)
1037 {
1038 if (wMinValueG > 20)
1039 {
1040 if (g_chip.AD.OffsetG < 8)
1041 g_chip.AD.DirectionG = 1;
1042 else
1043 g_chip.AD.OffsetG -= 8;
1044 }
1045 else if (wMinValueG < 10)
1046 g_chip.AD.OffsetG += 8;
1047 }
1048 else
1049 {
1050 if (wMinValueG > 20)
1051 g_chip.AD.OffsetG += 8;
1052 else if (wMinValueG < 10)
1053 g_chip.AD.OffsetG -= 8;
1054 }
1055
1056 if (g_chip.AD.DirectionB == 0)
1057 {
1058 if (wMinValueB > 20)
1059 {
1060 if (g_chip.AD.OffsetB < 8)
1061 g_chip.AD.DirectionB = 1;
1062 else
1063 g_chip.AD.OffsetB -= 8;
1064 }
1065 else if (wMinValueB < 10)
1066 g_chip.AD.OffsetB += 8;
1067 }
1068 else
1069 {
1070 if (wMinValueB > 20)
1071 g_chip.AD.OffsetB += 8;
1072 else if (wMinValueB < 10)
1073 g_chip.AD.OffsetB -= 8;
1074 }
1075
1076 nTimesOfCal++;
1077 if (nTimesOfCal > 8)
1078 break;
1079
1080 }
1081 while (wMinValueR > 20 || wMinValueR < 10
1082 || wMinValueG > 20 || wMinValueG < 10
1083 || wMinValueB > 20 || wMinValueB < 10);
1084
1085 DBG (DBG_FUNC,
1086 "Reflective_AdjustAD: run in second adjust offset do-while\n");
1087
1088 DBG (DBG_FUNC, "Reflective_AdjustAD:after ad gain\n");
1089 DBG (DBG_FUNC, "Reflective_AdjustAD: "
1090 "g_chip.AD.GainR = %d,"
1091 "g_chip.AD.GainG = %d,"
1092 "g_chip.AD.GainB = %d\n",
1093 g_chip.AD.GainR, g_chip.AD.GainG, g_chip.AD.GainB);
1094
1095 free (lpCalData);
1096
1097 DBG (DBG_FUNC, "Reflective_AdjustAD: leave Reflective_AdjustAD\n");
1098 return TRUE;
1099 }
1100
1101 /**********************************************************************
1102 Author: Jack Date: 2005/05/14
1103 Routine Description:
1104 Find top and left side
1105 Parameters:
1106 lpwStartX: the left side
1107 lpwStartY: the top side
1108 Return value:
1109 if operation is success
1110 return TRUE
1111 else
1112 return FALSE
1113 ***********************************************************************/
1114 static SANE_Bool
Reflective_FindTopLeft(unsigned short * lpwStartX,unsigned short * lpwStartY)1115 Reflective_FindTopLeft (unsigned short * lpwStartX, unsigned short * lpwStartY)
1116 {
1117 unsigned short wCalWidth = FIND_LEFT_TOP_WIDTH_IN_DIP;
1118 unsigned short wCalHeight = FIND_LEFT_TOP_HEIGHT_IN_DIP;
1119
1120 int i, j;
1121 unsigned short wLeftSide;
1122 unsigned short wTopSide;
1123 int nScanBlock;
1124 SANE_Byte * lpCalData;
1125 unsigned int dwTotalSize;
1126 unsigned short wXResolution, wYResolution;
1127
1128 DBG (DBG_FUNC, "Reflective_FindTopLeft: call in\n");
1129 if (!g_bOpened)
1130 {
1131 DBG (DBG_FUNC, "Reflective_FindTopLeft: scanner has been opened\n");
1132 return FALSE;
1133 }
1134 if (!g_bPrepared)
1135 {
1136 DBG (DBG_FUNC, "Reflective_FindTopLeft: scanner not prepared\n");
1137 return FALSE;
1138 }
1139
1140 wXResolution = wYResolution = FIND_LEFT_TOP_CALIBRATE_RESOLUTION;
1141
1142 lpCalData = (SANE_Byte *) malloc (sizeof (SANE_Byte) * wCalWidth * wCalHeight);
1143 if (lpCalData == NULL)
1144 {
1145 DBG (DBG_FUNC, "Reflective_FindTopLeft: lpCalData malloc error\n");
1146 return FALSE;
1147 }
1148
1149 dwTotalSize = wCalWidth * wCalHeight;
1150 nScanBlock = (int) (dwTotalSize / g_dwCalibrationSize);
1151
1152 Asic_SetMotorType (&g_chip, TRUE, TRUE);
1153 Asic_SetCalibrate (&g_chip, 8, wXResolution, wYResolution, 0, 0, wCalWidth,
1154 wCalHeight, FALSE);
1155 Asic_SetAFEGainOffset (&g_chip);
1156 if (Asic_ScanStart (&g_chip) != SANE_STATUS_GOOD)
1157 {
1158 DBG (DBG_FUNC, "Reflective_FindTopLeft: Asic_ScanStart return error\n");
1159 free (lpCalData);
1160 return FALSE;
1161 }
1162
1163 for (i = 0; i < nScanBlock; i++)
1164 {
1165 if (SANE_STATUS_GOOD !=
1166 Asic_ReadCalibrationData (&g_chip,
1167 lpCalData + i * g_dwCalibrationSize,
1168 g_dwCalibrationSize, 8))
1169 {
1170 DBG (DBG_FUNC,
1171 "Reflective_FindTopLeft: Asic_ReadCalibrationData return error\n");
1172 free (lpCalData);
1173 return FALSE;
1174 }
1175 }
1176
1177 if (SANE_STATUS_GOOD !=
1178 Asic_ReadCalibrationData (&g_chip,
1179 lpCalData +
1180 (nScanBlock) * g_dwCalibrationSize,
1181 (dwTotalSize -
1182 g_dwCalibrationSize * nScanBlock), 8))
1183 {
1184
1185 DBG (DBG_FUNC,
1186 "Reflective_FindTopLeft: Asic_ReadCalibrationData return error\n");
1187 free (lpCalData);
1188 return FALSE;
1189 }
1190
1191 Asic_ScanStop (&g_chip);
1192
1193 #ifdef DEBUG_SAVE_IMAGE
1194 FILE *stream = NULL;
1195 stream = fopen ("/root/bound(Ref).pnm", "wb+\n");
1196 SANE_Byte * lpBuf = (SANE_Byte *) malloc (50);
1197 if (NULL == lpBuf)
1198 {
1199 return FALSE;
1200 }
1201 memset (lpBuf, 0, 50);
1202 sprintf (lpBuf, "P5\n%d %d\n255\n", wCalWidth, wCalHeight);
1203 fwrite (lpBuf, sizeof (SANE_Byte), strlen (lpBuf), stream);
1204 fwrite (lpCalData, sizeof (SANE_Byte), wCalWidth * wCalHeight, stream);
1205
1206 fclose (stream);
1207 free (lpBuf);
1208 #endif
1209
1210 wLeftSide = 0;
1211 wTopSide = 0;
1212
1213 /* Find Left Side */
1214 for (i = wCalWidth - 1; i > 0; i--)
1215 {
1216 wLeftSide = *(lpCalData + i);
1217 wLeftSide += *(lpCalData + wCalWidth * 2 + i);
1218 wLeftSide += *(lpCalData + wCalWidth * 4 + i);
1219 wLeftSide += *(lpCalData + wCalWidth * 6 + i);
1220 wLeftSide += *(lpCalData + wCalWidth * 8 + i);
1221 wLeftSide /= 5;
1222 if (wLeftSide < 60)
1223 {
1224 if (i == wCalWidth - 1)
1225 {
1226 break;
1227 }
1228 *lpwStartX = i;
1229 {
1230 break;
1231 }
1232 }
1233 }
1234
1235 /*Find Top Side i=left side */
1236 for (j = 0; j < wCalHeight; j++)
1237 {
1238 wTopSide = *(lpCalData + wCalWidth * j + i - 2);
1239 wTopSide += *(lpCalData + wCalWidth * j + i - 4);
1240 wTopSide += *(lpCalData + wCalWidth * j + i - 6);
1241 wTopSide += *(lpCalData + wCalWidth * j + i - 8);
1242 wTopSide += *(lpCalData + wCalWidth * j + i - 10);
1243
1244 wTopSide /= 5;
1245 if (wTopSide > 60)
1246 {
1247 if (j == 0)
1248 {
1249 break;
1250 }
1251 *lpwStartY = j;
1252 {
1253 break;
1254 }
1255 }
1256 }
1257
1258 if ((*lpwStartX < 100) || (*lpwStartX > 250))
1259 {
1260 *lpwStartX = 187;
1261 }
1262
1263 if ((*lpwStartY < 10) || (*lpwStartY > 100))
1264 {
1265 *lpwStartY = 43;
1266 }
1267
1268 DBG (DBG_FUNC,
1269 "Reflective_FindTopLeft: *lpwStartY = %d, *lpwStartX = %d\n",
1270 *lpwStartY, *lpwStartX);
1271 Asic_MotorMove (&g_chip, FALSE,
1272 (wCalHeight - *lpwStartY +
1273 BEFORE_SCANNING_MOTOR_FORWARD_PIXEL) * 1200 /
1274 wYResolution);
1275
1276 free (lpCalData);
1277
1278 DBG (DBG_FUNC, "Reflective_FindTopLeft: leave Reflective_FindTopLeft\n");
1279 return TRUE;
1280
1281 }
1282
1283 /**********************************************************************
1284 Author: Jack Date: 2005/05/14
1285 Routine Description:
1286 Stop scan
1287 Parameters:
1288 none
1289 Return value:
1290 if operation is success
1291 return TRUE
1292 else
1293 return FALSE
1294 ***********************************************************************/
1295 static SANE_Bool
Reflective_StopScan()1296 Reflective_StopScan ()
1297 {
1298 DBG (DBG_FUNC, "Reflective_StopScan: call in\n");
1299 if (!g_bOpened)
1300 {
1301 DBG (DBG_FUNC, "Reflective_StopScan: scanner not opened\n");
1302
1303 return FALSE;
1304 }
1305 if (!g_bPrepared)
1306 {
1307 DBG (DBG_FUNC, "Reflective_StopScan: scanner not prepared\n");
1308
1309 return FALSE;
1310 }
1311
1312 g_isCanceled = TRUE; /*tell parent process stop read image */
1313
1314 pthread_cancel (g_threadid_readimage);
1315 pthread_join (g_threadid_readimage, NULL);
1316
1317 DBG (DBG_FUNC, "Reflective_StopScan: thread exit\n");
1318
1319 Asic_ScanStop (&g_chip);
1320 Asic_Close (&g_chip);
1321
1322 g_bOpened = FALSE;
1323
1324 DBG (DBG_FUNC, "Reflective_StopScan: leave Reflective_StopScan\n");
1325 return TRUE;
1326 }
1327
1328 /**********************************************************************
1329 Author: Jack Date: 2005/05/15
1330 Routine Description:
1331 Get the calibration data
1332 Parameters:
1333 none
1334 Return value:
1335 if the operation is success
1336 return TRUE
1337 else
1338 return FALSE
1339 ***********************************************************************/
1340 static SANE_Bool
Reflective_LineCalibration16Bits()1341 Reflective_LineCalibration16Bits ()
1342 {
1343 SANE_Status status;
1344 SANE_Byte * lpWhiteData;
1345 SANE_Byte * lpDarkData;
1346 unsigned int dwWhiteTotalSize;
1347 unsigned int dwDarkTotalSize;
1348 unsigned short wCalHeight = LINE_CALIBRATION__16BITS_HEIGHT;
1349 unsigned short wCalWidth;
1350
1351 unsigned short *lpWhiteShading;
1352 unsigned short *lpDarkShading;
1353 double wRWhiteLevel = 0;
1354 double wGWhiteLevel = 0;
1355 double wBWhiteLevel = 0;
1356 unsigned int dwRDarkLevel = 0;
1357 unsigned int dwGDarkLevel = 0;
1358 unsigned int dwBDarkLevel = 0;
1359 unsigned int dwREvenDarkLevel = 0;
1360 unsigned int dwGEvenDarkLevel = 0;
1361 unsigned int dwBEvenDarkLevel = 0;
1362 unsigned short * lpRWhiteSort;
1363 unsigned short * lpGWhiteSort;
1364 unsigned short * lpBWhiteSort;
1365 unsigned short * lpRDarkSort;
1366 unsigned short * lpGDarkSort;
1367 unsigned short * lpBDarkSort;
1368 int i, j;
1369
1370 DBG (DBG_FUNC, "Reflective_LineCalibration16Bits: call in\n");
1371 if (!g_bOpened)
1372 {
1373 DBG (DBG_FUNC,
1374 "Reflective_LineCalibration16Bits: scanner not opened\n");
1375
1376 return FALSE;
1377 }
1378 if (!g_bPrepared)
1379 {
1380 DBG (DBG_FUNC,
1381 "Reflective_LineCalibration16Bits: scanner not prepared\n");
1382
1383 return FALSE;
1384 }
1385
1386 wCalWidth = g_Width;
1387
1388 dwWhiteTotalSize = wCalWidth * wCalHeight * 3 * 2;
1389 dwDarkTotalSize = wCalWidth * wCalHeight * 3 * 2;
1390 lpWhiteData = (SANE_Byte *) malloc (sizeof (SANE_Byte) * dwWhiteTotalSize);
1391 lpDarkData = (SANE_Byte *) malloc (sizeof (SANE_Byte) * dwDarkTotalSize);
1392
1393 if (lpWhiteData == NULL || lpDarkData == NULL)
1394 {
1395 DBG (DBG_FUNC,
1396 "Reflective_LineCalibration16Bits: lpWhiteData or lpDarkData malloc error \n");
1397
1398 return FALSE;
1399 }
1400
1401 Asic_SetMotorType (&g_chip, TRUE, TRUE);
1402 Asic_SetAFEGainOffset (&g_chip);
1403 status =
1404 Asic_SetCalibrate (&g_chip, 48, g_XDpi, g_YDpi, g_X, 0, wCalWidth,
1405 wCalHeight, TRUE);
1406 if (status != SANE_STATUS_GOOD)
1407 {
1408 DBG (DBG_FUNC,
1409 "Reflective_LineCalibration16Bits: Asic_SetCalibrate return error \n");
1410
1411 free (lpWhiteData);
1412
1413 free (lpDarkData);
1414 return FALSE;
1415 }
1416
1417 status = Asic_ScanStart (&g_chip);
1418 if (status != SANE_STATUS_GOOD)
1419 {
1420 DBG (DBG_FUNC,
1421 "Reflective_LineCalibration16Bits: Asic_ScanStart return error \n");
1422
1423 free (lpWhiteData);
1424 free (lpDarkData);
1425 return FALSE;
1426 }
1427
1428 status =
1429 Asic_ReadCalibrationData (&g_chip, lpWhiteData, dwWhiteTotalSize, 8);
1430 if (status != SANE_STATUS_GOOD)
1431 {
1432 free (lpWhiteData);
1433 free (lpDarkData);
1434 return FALSE;
1435 }
1436
1437 Asic_ScanStop (&g_chip);
1438
1439 /*Read dark level data */
1440 status = Asic_SetMotorType (&g_chip, FALSE, TRUE);
1441 if (status != SANE_STATUS_GOOD)
1442 {
1443 DBG (DBG_FUNC,
1444 "Reflective_LineCalibration16Bits: Asic_SetMotorType return error \n");
1445
1446 free (lpWhiteData);
1447 free (lpDarkData);
1448 return FALSE;
1449 }
1450
1451 status =
1452 Asic_SetCalibrate (&g_chip, 48, g_XDpi, g_YDpi, g_X, 0, wCalWidth,
1453 wCalHeight, TRUE);
1454 if (status != SANE_STATUS_GOOD)
1455 {
1456 DBG (DBG_FUNC,
1457 "Reflective_LineCalibration16Bits: Asic_SetCalibrate return error \n");
1458
1459 free (lpWhiteData);
1460 free (lpDarkData);
1461 return FALSE;
1462 }
1463
1464 status = Asic_TurnLamp (&g_chip, FALSE);
1465 if (status != SANE_STATUS_GOOD)
1466 {
1467 DBG (DBG_FUNC,
1468 "Reflective_LineCalibration16Bits: Asic_TurnLamp return error \n");
1469
1470 free (lpWhiteData);
1471 free (lpDarkData);
1472 return FALSE;
1473 }
1474
1475 usleep (500000);
1476
1477 status = Asic_ScanStart (&g_chip);
1478 if (status != SANE_STATUS_GOOD)
1479 {
1480 DBG (DBG_FUNC,
1481 "Reflective_LineCalibration16Bits: Asic_ScanStart return error \n");
1482
1483 free (lpWhiteData);
1484 free (lpDarkData);
1485 return FALSE;
1486 }
1487
1488 status = Asic_ReadCalibrationData (&g_chip, lpDarkData, dwDarkTotalSize, 8);
1489 if (status != SANE_STATUS_GOOD)
1490 {
1491 DBG (DBG_FUNC,
1492 "Reflective_LineCalibration16Bits: Asic_ReadCalibrationData return error \n");
1493
1494 free (lpWhiteData);
1495 free (lpDarkData);
1496 return FALSE;
1497 }
1498
1499 Asic_ScanStop (&g_chip);
1500
1501 /* Turn on lamp */
1502 status = Asic_TurnLamp (&g_chip, TRUE);
1503 if (status != SANE_STATUS_GOOD)
1504 {
1505 DBG (DBG_FUNC,
1506 "Reflective_LineCalibration16Bits: Asic_TurnLamp return error \n");
1507
1508 free (lpWhiteData);
1509 free (lpDarkData);
1510 return FALSE;
1511 }
1512
1513 #ifdef DEBUG_SAVE_IMAGE
1514 FILE *stream = NULL;
1515 SANE_Byte * lpBuf = (SANE_Byte *) malloc (50);
1516 if (NULL == lpBuf)
1517 {
1518 return FALSE;
1519
1520 }
1521 memset (lpBuf, 0, 50);
1522 stream = fopen ("/root/whiteshading(Ref).pnm", "wb+\n");
1523 sprintf (lpBuf, "P6\n%d %d\n65535\n", wCalWidth, wCalHeight);
1524 fwrite (lpBuf, sizeof (SANE_Byte), strlen (lpBuf), stream);
1525 fwrite (lpWhiteData, sizeof (SANE_Byte), wCalWidth * wCalHeight * 3 * 2, stream);
1526 fclose (stream);
1527
1528 memset (lpBuf, 0, 50);
1529 stream = fopen ("/root/darkshading(Ref).pnm", "wb+\n");
1530 sprintf (lpBuf, "P6\n%d %d\n65535\n", wCalWidth, wCalHeight);
1531 fwrite (lpBuf, sizeof (SANE_Byte), strlen (lpBuf), stream);
1532 fwrite (lpDarkData, sizeof (SANE_Byte), wCalWidth * wCalHeight * 3 * 2, stream);
1533 fclose (stream);
1534 free (lpBuf);
1535 #endif
1536
1537 sleep (1);
1538
1539 lpWhiteShading = (unsigned short *) malloc (sizeof (unsigned short) * wCalWidth * 3);
1540 lpDarkShading = (unsigned short *) malloc (sizeof (unsigned short) * wCalWidth * 3);
1541
1542 lpRWhiteSort = (unsigned short *) malloc (sizeof (unsigned short) * wCalHeight);
1543 lpGWhiteSort = (unsigned short *) malloc (sizeof (unsigned short) * wCalHeight);
1544 lpBWhiteSort = (unsigned short *) malloc (sizeof (unsigned short) * wCalHeight);
1545 lpRDarkSort = (unsigned short *) malloc (sizeof (unsigned short) * wCalHeight);
1546 lpGDarkSort = (unsigned short *) malloc (sizeof (unsigned short) * wCalHeight);
1547 lpBDarkSort = (unsigned short *) malloc (sizeof (unsigned short) * wCalHeight);
1548
1549 if (lpWhiteShading == NULL || lpDarkShading == NULL
1550 || lpRWhiteSort == NULL || lpGWhiteSort == NULL || lpBWhiteSort == NULL
1551 || lpRDarkSort == NULL || lpGDarkSort == NULL || lpBDarkSort == NULL)
1552 {
1553 DBG (DBG_FUNC, "Reflective_LineCalibration16Bits: malloc error \n");
1554
1555 free (lpWhiteData);
1556 free (lpDarkData);
1557 return FALSE;
1558 }
1559
1560 /* create dark level shading */
1561 dwRDarkLevel = 0;
1562 dwGDarkLevel = 0;
1563 dwBDarkLevel = 0;
1564 dwREvenDarkLevel = 0;
1565 dwGEvenDarkLevel = 0;
1566 dwBEvenDarkLevel = 0;
1567
1568 DBG (DBG_FUNC,
1569 "Reflective_LineCalibration16Bits: wCalWidth = %d, wCalHeight = %d\n",
1570 wCalWidth, wCalHeight);
1571
1572 for (i = 0; i < wCalWidth; i++)
1573 {
1574 for (j = 0; j < wCalHeight; j++)
1575 {
1576 lpRDarkSort[j] =
1577 (unsigned short) (*(lpDarkData + j * wCalWidth * 6 + i * 6 + 0));
1578 lpRDarkSort[j] +=
1579 (unsigned short) (*(lpDarkData + j * wCalWidth * 6 + i * 6 + 1) << 8);
1580
1581 lpGDarkSort[j] =
1582 (unsigned short) (*(lpDarkData + j * wCalWidth * 6 + i * 6 + 2));
1583 lpGDarkSort[j] +=
1584 (unsigned short) (*(lpDarkData + j * wCalWidth * 6 + i * 6 + 3) << 8);
1585
1586 lpBDarkSort[j] =
1587 (unsigned short) (*(lpDarkData + j * wCalWidth * 6 + i * 6 + 4));
1588 lpBDarkSort[j] +=
1589 (unsigned short) (*(lpDarkData + j * wCalWidth * 6 + i * 6 + 5) << 8);
1590 }
1591
1592 if (g_XDpi == 1200)
1593 {
1594
1595 /*do dark shading table with mean */
1596 if (i % 2)
1597 {
1598 dwRDarkLevel +=
1599 (unsigned int) MustScanner_FiltLower (lpRDarkSort, wCalHeight, 20,
1600 30);
1601 dwGDarkLevel +=
1602 (unsigned int) MustScanner_FiltLower (lpGDarkSort, wCalHeight, 20,
1603 30);
1604 dwBDarkLevel +=
1605 (unsigned int) MustScanner_FiltLower (lpBDarkSort, wCalHeight, 20,
1606 30);
1607 }
1608 else
1609 {
1610 dwREvenDarkLevel +=
1611 (unsigned int) MustScanner_FiltLower (lpRDarkSort, wCalHeight, 20,
1612 30);
1613
1614 dwGEvenDarkLevel +=
1615 (unsigned int) MustScanner_FiltLower (lpGDarkSort, wCalHeight, 20,
1616 30);
1617 dwBEvenDarkLevel +=
1618 (unsigned int) MustScanner_FiltLower (lpBDarkSort, wCalHeight, 20,
1619 30);
1620 }
1621 }
1622 else
1623 {
1624
1625 dwRDarkLevel +=
1626 (unsigned int) MustScanner_FiltLower (lpRDarkSort, wCalHeight, 20, 30);
1627 dwGDarkLevel +=
1628 (unsigned int) MustScanner_FiltLower (lpGDarkSort, wCalHeight, 20, 30);
1629 dwBDarkLevel +=
1630 (unsigned int) MustScanner_FiltLower (lpBDarkSort, wCalHeight, 20, 30);
1631 }
1632 }
1633
1634 if (g_XDpi == 1200)
1635 {
1636 dwRDarkLevel = (unsigned int) (dwRDarkLevel / (wCalWidth / 2));
1637 dwGDarkLevel = (unsigned int) (dwGDarkLevel / (wCalWidth / 2));
1638 dwBDarkLevel = (unsigned int) (dwBDarkLevel / (wCalWidth / 2));
1639 dwREvenDarkLevel = (unsigned int) (dwREvenDarkLevel / (wCalWidth / 2));
1640 dwGEvenDarkLevel = (unsigned int) (dwGEvenDarkLevel / (wCalWidth / 2));
1641 dwBEvenDarkLevel = (unsigned int) (dwBEvenDarkLevel / (wCalWidth / 2));
1642 }
1643 else
1644 {
1645 dwRDarkLevel = (unsigned int) (dwRDarkLevel / wCalWidth);
1646 dwGDarkLevel = (unsigned int) (dwGDarkLevel / wCalWidth);
1647 dwBDarkLevel = (unsigned int) (dwBDarkLevel / wCalWidth);
1648 }
1649
1650 /*Create white shading */
1651 for (i = 0; i < wCalWidth; i++)
1652 {
1653 wRWhiteLevel = 0;
1654 wGWhiteLevel = 0;
1655 wBWhiteLevel = 0;
1656
1657 for (j = 0; j < wCalHeight; j++)
1658 {
1659 lpRWhiteSort[j] =
1660 (unsigned short) (*(lpWhiteData + j * wCalWidth * 2 * 3 + i * 6 + 0));
1661 lpRWhiteSort[j] +=
1662 (unsigned short) (*(lpWhiteData + j * wCalWidth * 2 * 3 + i * 6 + 1) << 8);
1663
1664 lpGWhiteSort[j] =
1665 (unsigned short) (*(lpWhiteData + j * wCalWidth * 2 * 3 + i * 6 + 2));
1666 lpGWhiteSort[j] +=
1667 (unsigned short) (*(lpWhiteData + j * wCalWidth * 2 * 3 + i * 6 + 3) << 8);
1668
1669 lpBWhiteSort[j] =
1670 (unsigned short) (*(lpWhiteData + j * wCalWidth * 2 * 3 + i * 6 + 4));
1671 lpBWhiteSort[j] +=
1672 (unsigned short) (*(lpWhiteData + j * wCalWidth * 2 * 3 + i * 6 + 5) << 8);
1673 }
1674
1675 if (g_XDpi == 1200)
1676 {
1677 if (i % 2)
1678 {
1679 *(lpDarkShading + i * 3 + 0) = (unsigned short) dwRDarkLevel;
1680 *(lpDarkShading + i * 3 + 1) = (unsigned short) dwGDarkLevel;
1681 *(lpDarkShading + i * 3 + 2) = (unsigned short) dwBDarkLevel;
1682 }
1683 else
1684 {
1685 *(lpDarkShading + i * 3 + 0) = (unsigned short) dwREvenDarkLevel;
1686 *(lpDarkShading + i * 3 + 1) = (unsigned short) dwGEvenDarkLevel;
1687 *(lpDarkShading + i * 3 + 2) = (unsigned short) dwBEvenDarkLevel;
1688 }
1689 }
1690 else
1691 {
1692 *(lpDarkShading + i * 3 + 0) = (unsigned short) dwRDarkLevel;
1693 *(lpDarkShading + i * 3 + 1) = (unsigned short) dwGDarkLevel;
1694 *(lpDarkShading + i * 3 + 2) = (unsigned short) dwBDarkLevel;
1695 }
1696
1697
1698 /*Create white shading */
1699 wRWhiteLevel =
1700 (double) (MustScanner_FiltLower (lpRWhiteSort, wCalHeight, 20, 30) -
1701 *(lpDarkShading + i * 3 + 0));
1702 wGWhiteLevel =
1703 (double) (MustScanner_FiltLower (lpGWhiteSort, wCalHeight, 20, 30) -
1704 *(lpDarkShading + i * 3 + 1));
1705 wBWhiteLevel =
1706 (double) (MustScanner_FiltLower (lpBWhiteSort, wCalHeight, 20, 30) -
1707 *(lpDarkShading + i * 3 + 2));
1708
1709 if (wRWhiteLevel > 0)
1710 *(lpWhiteShading + i * 3 + 0) =
1711 (unsigned short) (((float) 65535 / wRWhiteLevel * 0x2000));
1712 else
1713 *(lpWhiteShading + i * 3 + 0) = 0x2000;
1714
1715 if (wGWhiteLevel > 0)
1716 *(lpWhiteShading + i * 3 + 1) =
1717 (unsigned short) (((float) 65535 / wGWhiteLevel * 0x2000));
1718 else
1719 *(lpWhiteShading + i * 3 + 1) = 0x2000;
1720
1721 if (wBWhiteLevel > 0)
1722 *(lpWhiteShading + i * 3 + 2) =
1723 (unsigned short) (((float) 65535 / wBWhiteLevel * 0x2000));
1724 else
1725 *(lpWhiteShading + i * 3 + 2) = 0x2000;
1726 }
1727
1728 free (lpWhiteData);
1729 free (lpDarkData);
1730 free (lpRWhiteSort);
1731 free (lpGWhiteSort);
1732 free (lpBWhiteSort);
1733 free (lpRDarkSort);
1734 free (lpGDarkSort);
1735 free (lpBDarkSort);
1736
1737 Asic_SetShadingTable (&g_chip, lpWhiteShading, lpDarkShading, g_XDpi,
1738 wCalWidth, 0);
1739
1740 free (lpWhiteShading);
1741 free (lpDarkShading);
1742
1743 DBG (DBG_FUNC,
1744 "Reflective_LineCalibration16Bits: leave Reflective_LineCalibration16Bits\n");
1745 return TRUE;
1746 }
1747
1748 /**********************************************************************
1749 Author: Jack Date: 2005/05/14
1750 Routine Description:
1751 Prepare scan image
1752 Parameters:
1753 none
1754 Return value:
1755 if operation is success
1756 return TRUE
1757 else
1758 return FALSE
1759 ***********************************************************************/
1760 static SANE_Bool
Reflective_PrepareScan()1761 Reflective_PrepareScan ()
1762 {
1763 g_wScanLinesPerBlock = g_dwBufferSize / g_BytesPerRow;
1764 g_wMaxScanLines = g_dwImageBufferSize / g_BytesPerRow;
1765 g_wMaxScanLines =
1766 (g_wMaxScanLines / g_wScanLinesPerBlock) * g_wScanLinesPerBlock;
1767
1768 g_isCanceled = FALSE;
1769
1770 g_dwScannedTotalLines = 0;
1771 g_wReadedLines = 0;
1772 g_wtheReadyLines = 0;
1773 g_wReadImageLines = 0;
1774
1775 g_wReadyShadingLine = 0;
1776 g_wStartShadingLinePos = 0;
1777
1778 switch (g_ScanMode)
1779 {
1780 case CM_RGB48:
1781 g_wtheReadyLines = g_wLineDistance * 2 + g_wPixelDistance;
1782 DBG (DBG_FUNC, "Reflective_PrepareScan:g_wtheReadyLines=%d\n",
1783 g_wtheReadyLines);
1784
1785 DBG (DBG_FUNC,
1786 "Reflective_PrepareScan:g_lpReadImageHead malloc %d Bytes\n",
1787 g_dwImageBufferSize);
1788 g_lpReadImageHead = (SANE_Byte *) malloc (g_dwImageBufferSize);
1789 if (g_lpReadImageHead == NULL)
1790 {
1791 DBG (DBG_FUNC,
1792 "Reflective_PrepareScan: g_lpReadImageHead malloc error \n");
1793 return FALSE;
1794 }
1795 break;
1796
1797 case CM_RGB24ext:
1798 g_wtheReadyLines = g_wLineDistance * 2 + g_wPixelDistance;
1799 DBG (DBG_FUNC, "Reflective_PrepareScan:g_wtheReadyLines=%d\n",
1800 g_wtheReadyLines);
1801
1802 DBG (DBG_FUNC,
1803 "Reflective_PrepareScan:g_lpReadImageHead malloc %d Bytes\n",
1804 g_dwImageBufferSize);
1805 g_lpReadImageHead = (SANE_Byte *) malloc (g_dwImageBufferSize);
1806 if (g_lpReadImageHead == NULL)
1807 {
1808 DBG (DBG_FUNC,
1809 "Reflective_PrepareScan: g_lpReadImageHead malloc error \n");
1810 return FALSE;
1811 }
1812 break;
1813 case CM_GRAY16ext:
1814 g_wtheReadyLines = g_wPixelDistance;
1815 DBG (DBG_FUNC, "Reflective_PrepareScan:g_wtheReadyLines=%d\n",
1816 g_wtheReadyLines);
1817
1818 DBG (DBG_FUNC,
1819 "Reflective_PrepareScan:g_lpReadImageHead malloc %d Bytes\n",
1820 g_dwImageBufferSize);
1821 g_lpReadImageHead = (SANE_Byte *) malloc (g_dwImageBufferSize);
1822 if (g_lpReadImageHead == NULL)
1823 {
1824 DBG (DBG_FUNC,
1825 "Reflective_PrepareScan: g_lpReadImageHead malloc error \n");
1826 return FALSE;
1827 }
1828 break;
1829 case CM_GRAY8ext:
1830 g_wtheReadyLines = g_wPixelDistance;
1831 DBG (DBG_FUNC, "Reflective_PrepareScan:g_wtheReadyLines=%d\n",
1832 g_wtheReadyLines);
1833
1834 DBG (DBG_FUNC,
1835 "Reflective_PrepareScan:g_lpReadImageHead malloc %d Bytes\n",
1836 g_dwImageBufferSize);
1837 g_lpReadImageHead = (SANE_Byte *) malloc (g_dwImageBufferSize);
1838 if (g_lpReadImageHead == NULL)
1839 {
1840 DBG (DBG_FUNC,
1841 "Reflective_PrepareScan: g_lpReadImageHead malloc error \n");
1842 return FALSE;
1843 }
1844 break;
1845 case CM_TEXT:
1846 g_wtheReadyLines = g_wPixelDistance;
1847 DBG (DBG_FUNC, "Reflective_PrepareScan:g_wtheReadyLines=%d\n",
1848 g_wtheReadyLines);
1849
1850 DBG (DBG_FUNC,
1851 "Reflective_PrepareScan:g_lpReadImageHead malloc %d Bytes\n",
1852 g_dwImageBufferSize);
1853 g_lpReadImageHead = (SANE_Byte *) malloc (g_dwImageBufferSize);
1854 if (g_lpReadImageHead == NULL)
1855 {
1856 DBG (DBG_FUNC,
1857 "Reflective_PrepareScan: g_lpReadImageHead malloc error \n");
1858 return FALSE;
1859 }
1860 break;
1861 default:
1862 break;
1863 }
1864
1865 Asic_ScanStart (&g_chip);
1866 return TRUE;
1867 }
1868
1869 /**********************************************************************
1870 Author: Jack Date: 2005/05/15
1871 Routine Description:
1872 Get the data of image
1873 Parameters:
1874 lpBlock: the data of image
1875 Rows: the rows of image
1876
1877 isOrderInvert: the RGB order
1878 Return value:
1879 if the operation is success
1880 return TRUE
1881 else
1882 return FALSE
1883 ***********************************************************************/
1884 static SANE_Bool
Reflective_GetRows(SANE_Byte * lpBlock,unsigned short * Rows,SANE_Bool isOrderInvert)1885 Reflective_GetRows (SANE_Byte * lpBlock, unsigned short * Rows, SANE_Bool isOrderInvert)
1886 {
1887 DBG (DBG_FUNC, "Reflective_GetRows: call in \n");
1888 if (!g_bOpened)
1889 {
1890 DBG (DBG_FUNC, "Reflective_GetRows: scanner not opened \n");
1891 return FALSE;
1892 }
1893 if (!g_bPrepared)
1894 {
1895 DBG (DBG_FUNC, "Reflective_GetRows: scanner not prepared \n");
1896 return FALSE;
1897 }
1898
1899 switch (g_ScanMode)
1900 {
1901 case CM_RGB48:
1902 if (g_XDpi == 1200)
1903 return MustScanner_GetRgb48BitLine1200DPI (lpBlock, isOrderInvert,
1904 Rows);
1905 else
1906 return MustScanner_GetRgb48BitLine (lpBlock, isOrderInvert, Rows);
1907
1908 case CM_RGB24ext:
1909 if (g_XDpi == 1200)
1910 return MustScanner_GetRgb24BitLine1200DPI (lpBlock, isOrderInvert,
1911 Rows);
1912 else
1913 return MustScanner_GetRgb24BitLine (lpBlock, isOrderInvert, Rows);
1914
1915 case CM_GRAY16ext:
1916 if (g_XDpi == 1200)
1917 return MustScanner_GetMono16BitLine1200DPI (lpBlock, isOrderInvert,
1918 Rows);
1919 else
1920 return MustScanner_GetMono16BitLine (lpBlock, isOrderInvert, Rows);
1921
1922 case CM_GRAY8ext:
1923 if (g_XDpi == 1200)
1924 return MustScanner_GetMono8BitLine1200DPI (lpBlock, isOrderInvert,
1925 Rows);
1926 else
1927 return MustScanner_GetMono8BitLine (lpBlock, isOrderInvert, Rows);
1928
1929 case CM_TEXT:
1930 if (g_XDpi == 1200)
1931 return MustScanner_GetMono1BitLine1200DPI (lpBlock, isOrderInvert,
1932 Rows);
1933 else
1934 return MustScanner_GetMono1BitLine (lpBlock, isOrderInvert, Rows);
1935 default:
1936 return FALSE;
1937 }
1938
1939 DBG (DBG_FUNC, "Reflective_GetRows: leave Reflective_GetRows \n");
1940 return FALSE;
1941 } /* end of the file ScannerReflective.c */
1942