• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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