1 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback __sane_unused__ authorize)2 sane_init (SANE_Int * version_code, SANE_Auth_Callback __sane_unused__ authorize)
3 {
4   char devnam[PATH_MAX] = "/dev/scanner";
5   FILE *fp;
6 
7   int i, j;
8   SANE_Byte primary, secondary, inmask, priMask, secMask;
9 
10   DBG_INIT ();
11   DBG (1, ">> sane_init\n");
12 
13 /****** for lineart mode of FB1200S ******/
14   for (i = 0; i < 256; i++)
15     {
16       primary = secondary = 0;
17       inmask = 0x80;
18       priMask = 0x40;
19       secMask = 0x80;
20       for (j = 0; j < 4; j++)
21         {
22           if (i & inmask)
23             {
24               primary |= priMask;
25 	      secondary |= secMask;
26 	    }
27 	  priMask = priMask >> 2;
28 	  secMask = secMask >> 2;
29 	  inmask  = inmask >> 1;
30 	}
31       primaryHigh[i] = primary;
32       secondaryHigh[i] = secondary;
33 
34       primary = secondary = 0;
35       priMask = 0x40;
36       secMask = 0x80;
37       for (j = 0; j < 4; j++)
38 	{
39 	  if (i & inmask)
40 	    {
41 	      primary |= priMask;
42 	      secondary |= secMask;
43 	    }
44 	  priMask = priMask >> 2;
45 	  secMask = secMask >> 2;
46 	  inmask  = inmask >> 1;
47 	}
48       primaryLow[i] = primary;
49       secondaryLow[i] = secondary;
50     }
51 /******************************************/
52 
53 #if defined PACKAGE && defined VERSION
54   DBG (2, "sane_init: " PACKAGE " " VERSION "\n");
55 #endif
56 
57   if (version_code)
58     *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, V_MINOR, 0);
59 
60   fp = sanei_config_open (CANON_CONFIG_FILE);
61   if (fp)
62     {
63       char line[PATH_MAX];
64       size_t len;
65 
66       /* read config file */
67       /* while (fgets (line, sizeof (line), fp)) */
68       while (sanei_config_read (line, sizeof (line), fp))
69 	{
70 	  if (line[0] == '#')	/* ignore line comments */
71 	    continue;
72 	  len = strlen (line);
73 	  /*if (line[len - 1] == '\n')
74 	     line[--len] = '\0'; */
75 
76 	  if (!len)
77 	    continue;		/* ignore empty lines */
78 	  strcpy (devnam, line);
79 	}
80       fclose (fp);
81     }
82   sanei_config_attach_matching_devices (devnam, attach_one);
83   DBG (1, "<< sane_init\n");
84   return SANE_STATUS_GOOD;
85 }
86 
87 /**************************************************************************/
88 
89 void
sane_exit(void)90 sane_exit (void)
91 {
92   CANON_Device *dev, *next;
93   DBG (1, ">> sane_exit\n");
94 
95   for (dev = first_dev; dev; dev = next)
96     {
97       next = dev->next;
98       free ((void *) dev->sane.name);
99       free ((void *) dev->sane.model);
100       free ((void *) dev);
101     }
102 
103   DBG (1, "<< sane_exit\n");
104 }
105 
106 /**************************************************************************/
107 
108 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool __sane_unused__ local_only)109 sane_get_devices (const SANE_Device *** device_list,
110 SANE_Bool __sane_unused__ local_only)
111 {
112   static const SANE_Device **devlist = 0;
113   CANON_Device *dev;
114   int i;
115   DBG (1, ">> sane_get_devices\n");
116 
117   if (devlist)
118     free (devlist);
119   devlist = malloc ((num_devices + 1) * sizeof (devlist[0]));
120   if (!devlist)
121     return (SANE_STATUS_NO_MEM);
122 
123   i = 0;
124   for (dev = first_dev; dev; dev = dev->next)
125     devlist[i++] = &dev->sane;
126   devlist[i++] = 0;
127 
128   *device_list = devlist;
129 
130   DBG (1, "<< sane_get_devices\n");
131   return SANE_STATUS_GOOD;
132 }
133 
134 /**************************************************************************/
135 
136 SANE_Status
sane_open(SANE_String_Const devnam,SANE_Handle * handle)137 sane_open (SANE_String_Const devnam, SANE_Handle * handle)
138 {
139   SANE_Status status;
140   CANON_Device *dev;
141   CANON_Scanner *s;
142   int i, j, c;
143 
144   DBG (1, ">> sane_open\n");
145 
146   if (devnam[0] == '\0')
147     {
148       for (dev = first_dev; dev; dev = dev->next)
149 	{
150 	  if (strcmp (dev->sane.name, devnam) == 0)
151 	    break;
152 	}
153     }
154   else
155     dev = first_dev;
156 
157   if (!dev)
158     {
159       status = attach (devnam, &dev);
160       if (status != SANE_STATUS_GOOD)
161 	return (status);
162     }
163 
164 
165   if (!dev)
166     return (SANE_STATUS_INVAL);
167 
168   s = malloc (sizeof (*s));
169   if (!s)
170     return SANE_STATUS_NO_MEM;
171   memset (s, 0, sizeof (*s));
172 
173   s->fd = -1;
174   s->hw = dev;
175 
176   if (s->hw->info.model == FS2710)
177     {
178       for (i = 0; i < 4; i++)
179 	{
180 	  s->gamma_map[i][0] = '\0';
181 	  s->gamma_table[i][0] = 0;
182 	}
183       for (j = 1; j < 4096; ++j)
184 	{			/* FS2710 needs initial gamma 2.0 */
185 	  c = (int) (256.0 * pow (((double) j) / 4096.0, 0.5));
186 	  for (i = 0; i < 4; i++)
187 	    {
188 	      s->gamma_map[i][j] = (u_char) c;
189 	      if ((j & 0xf) == 0)
190 		s->gamma_table[i][j >> 4] = c;
191 	    }
192 	}
193       s->colour = 1;
194       s->auxbuf_len = 0;
195     }
196   else
197     {
198       for (i = 0; i < 4; ++i)
199 	{
200 	  for (j = 0; j < 256; ++j)
201 	    s->gamma_table[i][j] = j;
202 	}
203     }
204 
205   init_options (s);
206 
207   if (s->hw->info.model == FB1200)
208     s->inbuffer = malloc (30894);	/* modification for FB1200S */
209   else
210     s->inbuffer = malloc (15312);	/* modification for FB620S */
211 
212   if (!s->inbuffer)
213     return SANE_STATUS_NO_MEM;
214 
215   if (s->hw->info.model == FB1200)
216     s->outbuffer = malloc (30894);	/* modification for FB1200S */
217   else
218     s->outbuffer = malloc (15312);	/* modification for FB620S */
219 
220   if (!s->outbuffer)
221     {
222       free (s->inbuffer);
223       return SANE_STATUS_NO_MEM;
224     }
225 
226   s->next = first_handle;
227   first_handle = s;
228 
229   *handle = s;
230 
231   DBG (1, "<< sane_open\n");
232   return SANE_STATUS_GOOD;
233 
234 }
235 
236 /**************************************************************************/
237 
238 void
sane_close(SANE_Handle handle)239 sane_close (SANE_Handle handle)
240 {
241   CANON_Scanner *s = (CANON_Scanner *) handle;
242   SANE_Status status;
243 
244   DBG (1, ">> sane_close\n");
245 
246   if (s->val[OPT_EJECT_BEFOREEXIT].w)
247     {
248       if (s->fd == -1)
249 	sanei_scsi_open (s->hw->sane.name, &s->fd, sense_handler, s->hw);
250       status = medium_position (s->fd);
251       if (status != SANE_STATUS_GOOD)
252 	{
253 	  DBG (1, "sane_close: MEDIUM POSITION failed\n");
254 	  sanei_scsi_close (s->fd);
255 	  s->fd = -1;
256 	}
257       s->AF_NOW = SANE_TRUE;
258       DBG (1, "sane_close AF_NOW = '%d'\n", s->AF_NOW);
259     }
260 
261   if (s->fd != -1)
262     sanei_scsi_close (s->fd);
263 
264   if (s->inbuffer)
265     free (s->inbuffer);		/* modification for FB620S */
266   if (s->outbuffer)
267     free (s->outbuffer);	/* modification for FB620S */
268   if (s->auxbuf_len > 0)
269     free (s->auxbuf);		/* modification for FS2710S */
270 
271   free (s);
272 
273   DBG (1, ">> sane_close\n");
274 }
275 
276 /**************************************************************************/
277 
278 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle,SANE_Int option)279 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
280 {
281   CANON_Scanner *s = handle;
282   DBG (21, ">> sane_get_option_descriptor option number %d\n", option);
283 
284   if ((unsigned) option >= NUM_OPTIONS)
285     return (0);
286 
287   DBG (21, "   sane_get_option_descriptor option name %s\n",
288        option_name[option]);
289 
290   DBG (21, "<< sane_get_option_descriptor option number %d\n", option);
291   return (s->opt + option);
292 }
293 
294 /**************************************************************************/
295 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * val,SANE_Int * info)296 sane_control_option (SANE_Handle handle, SANE_Int option,
297 		     SANE_Action action, void *val, SANE_Int * info)
298 {
299   CANON_Scanner *s = handle;
300   SANE_Status status;
301   SANE_Word w, cap;
302   SANE_Byte gbuf[4096];
303   size_t buf_size;
304   int i, neg, gamma_component, int_t, transfer_data_type;
305   time_t dtime, rt;
306 
307   DBG (21, ">> sane_control_option %s\n", option_name[option]);
308 
309   if (info)
310     *info = 0;
311 
312   if (s->scanning == SANE_TRUE)
313     {
314       DBG (21, ">> sane_control_option: device is busy scanning\n");
315       return (SANE_STATUS_DEVICE_BUSY);
316     }
317   if (option >= NUM_OPTIONS)
318     return (SANE_STATUS_INVAL);
319 
320   cap = s->opt[option].cap;
321   if (!SANE_OPTION_IS_ACTIVE (cap))
322     return (SANE_STATUS_INVAL);
323 
324   if (action == SANE_ACTION_GET_VALUE)
325     {
326       DBG (21, "sane_control_option get value of %s\n", option_name[option]);
327       switch (option)
328 	{
329 	  /* word options: */
330 	case OPT_FLATBED_ONLY:
331 	case OPT_TPU_ON:
332 	case OPT_TPU_PN:
333 	case OPT_TPU_TRANSPARENCY:
334 	case OPT_RESOLUTION_BIND:
335 	case OPT_HW_RESOLUTION_ONLY:	/* 990320, ss */
336 	case OPT_X_RESOLUTION:
337 	case OPT_Y_RESOLUTION:
338 	case OPT_TL_X:
339 	case OPT_TL_Y:
340 	case OPT_BR_X:
341 	case OPT_BR_Y:
342 	case OPT_NUM_OPTS:
343 	case OPT_BRIGHTNESS:
344 	case OPT_CONTRAST:
345 	case OPT_CUSTOM_GAMMA:
346 	case OPT_CUSTOM_GAMMA_BIND:
347 	case OPT_HNEGATIVE:
348 	  /*     case OPT_GRC: */
349 	case OPT_MIRROR:
350 	case OPT_AE:
351 	case OPT_PREVIEW:
352 	case OPT_BIND_HILO:
353 	case OPT_HILITE_R:
354 	case OPT_SHADOW_R:
355 	case OPT_HILITE_G:
356 	case OPT_SHADOW_G:
357 	case OPT_HILITE_B:
358 	case OPT_SHADOW_B:
359 	case OPT_EJECT_AFTERSCAN:
360 	case OPT_EJECT_BEFOREEXIT:
361 	case OPT_THRESHOLD:
362 	case OPT_AF:
363 	case OPT_AF_ONCE:
364 	case OPT_FOCUS:
365 	  if ((option >= OPT_NEGATIVE) && (option <= OPT_SHADOW_B))
366 	    {
367 	      DBG (21, "GET_VALUE for %s: s->val[%s].w = %d\n",
368 		   option_name[option], option_name[option],
369 		   s->val[option].w);
370 	    }
371 	  *(SANE_Word *) val = s->val[option].w;
372 	  DBG (21, "value for option %s: %d\n", option_name[option],
373 	       s->val[option].w);
374 	  return (SANE_STATUS_GOOD);
375 
376 	case OPT_GAMMA_VECTOR:
377 	case OPT_GAMMA_VECTOR_R:
378 	case OPT_GAMMA_VECTOR_G:
379 	case OPT_GAMMA_VECTOR_B:
380 
381 	  memset (gbuf, 0, sizeof (gbuf));
382 	  buf_size = 256;
383 	  transfer_data_type = 0x03;
384 
385 	  DBG (21, "sending GET_DENSITY_CURVE\n");
386 	  if (s->val[OPT_CUSTOM_GAMMA_BIND].w == SANE_TRUE)
387 	    /* If using bind analog gamma, option will be OPT_GAMMA_VECTOR.
388 	       In this case, use the curve for green                        */
389 	    gamma_component = 2;
390 	  else
391 	    /* Else use a different index for each curve */
392 	    gamma_component = option - OPT_GAMMA_VECTOR;
393 
394 	  /* Now get the values from the scanner */
395 	  if (s->hw->info.model != FS2710)
396 	    {
397 	      sanei_scsi_open (s->hw->sane.name, &s->fd, sense_handler, s->hw);
398 	      status =
399 		get_density_curve (s->fd, gamma_component, gbuf, &buf_size,
400 				   transfer_data_type);
401 	      sanei_scsi_close (s->fd);
402 	      s->fd = -1;
403 	      if (status != SANE_STATUS_GOOD)
404 		{
405 		  DBG (21, "GET_DENSITY_CURVE\n");
406 		  return (SANE_STATUS_INVAL);
407 		}
408 	    }
409 	  else
410 	    status =
411 	      get_density_curve_fs2710 (s, gamma_component, gbuf, &buf_size);
412 
413 	  neg = (s->hw->info.is_filmscanner) ?
414 	    strcmp (filmtype_list[1], s->val[OPT_NEGATIVE].s)
415 	    : s->val[OPT_HNEGATIVE].w;
416 
417 	  for (i = 0; i < 256; i++)
418 	    {
419 	      if (!neg)
420 		s->gamma_table[option - OPT_GAMMA_VECTOR][i] =
421 		  (SANE_Int) gbuf[i];
422 	      else
423 		s->gamma_table[option - OPT_GAMMA_VECTOR][i] =
424 		  255 - (SANE_Int) gbuf[255 - i];
425 	    }
426 
427 	  memcpy (val, s->val[option].wa, s->opt[option].size);
428 	  DBG (21, "value for option %s: %d\n", option_name[option],
429 	       s->val[option].w);
430 	  return (SANE_STATUS_GOOD);
431 
432 	  /* string options: */
433 	case OPT_TPU_DCM:
434 	case OPT_TPU_FILMTYPE:
435 	case OPT_MODE:
436 	case OPT_NEGATIVE:
437 	case OPT_NEGATIVE_TYPE:
438 	case OPT_SCANNING_SPEED:
439 	  strcpy (val, s->val[option].s);
440 	  DBG (21, "value for option %s: %s\n", option_name[option],
441 	       s->val[option].s);
442 	  return (SANE_STATUS_GOOD);
443 
444 	default:
445 	  val = 0;
446 	  return (SANE_STATUS_GOOD);
447 	}
448     }
449   else if (action == SANE_ACTION_SET_VALUE)
450     {
451       DBG (21, "sane_control_option set value for %s\n", option_name[option]);
452       if (!SANE_OPTION_IS_SETTABLE (cap))
453 	return (SANE_STATUS_INVAL);
454 
455       status = sanei_constrain_value (s->opt + option, val, info);
456 
457       if (status != SANE_STATUS_GOOD)
458 	return status;
459 
460       switch (option)
461 	{
462 	  /* (mostly) side-effect-free word options: */
463 	case OPT_TPU_PN:
464 	case OPT_TPU_TRANSPARENCY:
465 	case OPT_X_RESOLUTION:
466 	case OPT_Y_RESOLUTION:
467 	case OPT_TL_X:
468 	case OPT_TL_Y:
469 	case OPT_BR_X:
470 	case OPT_BR_Y:
471 	  if (info && s->val[option].w != *(SANE_Word *) val)
472 	    *info |= SANE_INFO_RELOAD_PARAMS;
473 	  /* fall through */
474 	case OPT_NUM_OPTS:
475 	case OPT_BRIGHTNESS:
476 	case OPT_CONTRAST:
477 	case OPT_THRESHOLD:
478 	case OPT_HNEGATIVE:
479 	  /*     case OPT_GRC: */
480 	case OPT_MIRROR:
481 	case OPT_AE:
482 	case OPT_PREVIEW:
483 	case OPT_HILITE_R:
484 	case OPT_SHADOW_R:
485 	case OPT_HILITE_G:
486 	case OPT_SHADOW_G:
487 	case OPT_HILITE_B:
488 	case OPT_SHADOW_B:
489 	case OPT_AF_ONCE:
490 	case OPT_FOCUS:
491 	case OPT_EJECT_AFTERSCAN:
492 	case OPT_EJECT_BEFOREEXIT:
493 	  s->val[option].w = *(SANE_Word *) val;
494 	  DBG (21, "SET_VALUE for %s: s->val[%s].w = %d\n",
495 	       option_name[option], option_name[option], s->val[option].w);
496 	  return (SANE_STATUS_GOOD);
497 
498 	case OPT_RESOLUTION_BIND:
499 	  if (s->val[option].w != *(SANE_Word *) val)
500 	    {
501 	      s->val[option].w = *(SANE_Word *) val;
502 
503 	      if (info)
504 		*info |= SANE_INFO_RELOAD_OPTIONS;
505 	      if (!s->val[option].w)
506 		{		/* don't bind */
507 		  s->opt[OPT_Y_RESOLUTION].cap &= ~SANE_CAP_INACTIVE;
508 		  s->opt[OPT_X_RESOLUTION].title =
509 		    SANE_TITLE_SCAN_X_RESOLUTION;
510 		  s->opt[OPT_X_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
511 		  s->opt[OPT_X_RESOLUTION].desc = SANE_DESC_SCAN_X_RESOLUTION;
512 		}
513 	      else
514 		{		/* bind */
515 		  s->opt[OPT_Y_RESOLUTION].cap |= SANE_CAP_INACTIVE;
516 		  s->opt[OPT_X_RESOLUTION].title = SANE_TITLE_SCAN_RESOLUTION;
517 		  s->opt[OPT_X_RESOLUTION].name = SANE_NAME_SCAN_RESOLUTION;
518 		  s->opt[OPT_X_RESOLUTION].desc = SANE_DESC_SCAN_RESOLUTION;
519 		}
520 	    }
521 	  return SANE_STATUS_GOOD;
522 
523 	  /* 990320, ss: switch between slider and option menu for resolution */
524 	case OPT_HW_RESOLUTION_ONLY:
525 	  if (s->val[option].w != *(SANE_Word *) val)
526 	    {
527 	      int iPos, xres, yres;
528 
529 	      s->val[option].w = *(SANE_Word *) val;
530 
531 	      if (info)
532 		*info |= SANE_INFO_RELOAD_OPTIONS;
533 	      if (!s->val[option].w)	/* use complete range */
534 		{
535 		  s->opt[OPT_X_RESOLUTION].constraint_type =
536 		    SANE_CONSTRAINT_RANGE;
537 		  s->opt[OPT_X_RESOLUTION].constraint.range =
538 		    &s->hw->info.xres_range;
539 		  s->opt[OPT_Y_RESOLUTION].constraint_type =
540 		    SANE_CONSTRAINT_RANGE;
541 		  s->opt[OPT_Y_RESOLUTION].constraint.range =
542 		    &s->hw->info.yres_range;
543 		}
544 	      else			/* use only hardware resolutions */
545 		{
546 		  s->opt[OPT_X_RESOLUTION].constraint_type =
547 		    SANE_CONSTRAINT_WORD_LIST;
548 		  s->opt[OPT_X_RESOLUTION].constraint.word_list =
549 		    s->xres_word_list;
550 		  s->opt[OPT_Y_RESOLUTION].constraint_type =
551 		    SANE_CONSTRAINT_WORD_LIST;
552 		  s->opt[OPT_Y_RESOLUTION].constraint.word_list =
553 		    s->yres_word_list;
554 
555 		  /* adjust resolutions */
556 		  xres = s->xres_word_list[1];
557 		  for (iPos = 0; iPos < s->xres_word_list[0]; iPos++)
558 		    {
559 		      if (s->val[OPT_X_RESOLUTION].w >=
560 			  s->xres_word_list[iPos + 1])
561 			xres = s->xres_word_list[iPos + 1];
562 		    }
563 		  s->val[OPT_X_RESOLUTION].w = xres;
564 
565 		  yres = s->yres_word_list[1];
566 		  for (iPos = 0; iPos < s->yres_word_list[0]; iPos++)
567 		    {
568 		      if (s->val[OPT_Y_RESOLUTION].w >=
569 			  s->yres_word_list[iPos + 1])
570 			yres = s->yres_word_list[iPos + 1];
571 		    }
572 		  s->val[OPT_Y_RESOLUTION].w = yres;
573 		}
574 	    }
575 	  return (SANE_STATUS_GOOD);
576 
577 	case OPT_BIND_HILO:
578 	  if (s->val[option].w != *(SANE_Word *) val)
579 	    {
580 	      s->val[option].w = *(SANE_Word *) val;
581 
582 	      if (info)
583 		*info |= SANE_INFO_RELOAD_OPTIONS;
584 	      if (!s->val[option].w)
585 		{		/* don't bind */
586 		  s->opt[OPT_HILITE_R].cap &= ~SANE_CAP_INACTIVE;
587 		  s->opt[OPT_SHADOW_R].cap &= ~SANE_CAP_INACTIVE;
588 		  s->opt[OPT_HILITE_B].cap &= ~SANE_CAP_INACTIVE;
589 		  s->opt[OPT_SHADOW_B].cap &= ~SANE_CAP_INACTIVE;
590 
591 		  s->opt[OPT_HILITE_G].title = SANE_TITLE_HIGHLIGHT_G;
592 		  s->opt[OPT_HILITE_G].name = SANE_NAME_HIGHLIGHT_G;
593 		  s->opt[OPT_HILITE_G].desc = SANE_DESC_HIGHLIGHT_G;
594 
595 		  s->opt[OPT_SHADOW_G].title = SANE_TITLE_SHADOW_G;
596 		  s->opt[OPT_SHADOW_G].name = SANE_NAME_SHADOW_G;
597 		  s->opt[OPT_SHADOW_G].desc = SANE_DESC_SHADOW_G;
598 		}
599 	      else
600 		{		/* bind */
601 		  s->opt[OPT_HILITE_R].cap |= SANE_CAP_INACTIVE;
602 		  s->opt[OPT_SHADOW_R].cap |= SANE_CAP_INACTIVE;
603 		  s->opt[OPT_HILITE_B].cap |= SANE_CAP_INACTIVE;
604 		  s->opt[OPT_SHADOW_B].cap |= SANE_CAP_INACTIVE;
605 
606 		  s->opt[OPT_HILITE_G].title = SANE_TITLE_HIGHLIGHT;
607 		  s->opt[OPT_HILITE_G].name = SANE_NAME_HIGHLIGHT;
608 		  s->opt[OPT_HILITE_G].desc = SANE_DESC_HIGHLIGHT;
609 
610 		  s->opt[OPT_SHADOW_G].title = SANE_TITLE_SHADOW;
611 		  s->opt[OPT_SHADOW_G].name = SANE_NAME_SHADOW;
612 		  s->opt[OPT_SHADOW_G].desc = SANE_DESC_SHADOW;
613 		}
614 	    }
615 	  return SANE_STATUS_GOOD;
616 
617 	case OPT_AF:
618 	  if (info && s->val[option].w != *(SANE_Word *) val)
619 	    *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
620 	  s->val[option].w = *(SANE_Word *) val;
621 	  w = *(SANE_Word *) val;
622 	  if (w)
623 	    {
624 	      s->opt[OPT_AF_ONCE].cap &= ~SANE_CAP_INACTIVE;
625 	      s->opt[OPT_FOCUS].cap |= SANE_CAP_INACTIVE;
626 	    }
627 	  else
628 	    {
629 	      s->opt[OPT_AF_ONCE].cap |= SANE_CAP_INACTIVE;
630 	      s->opt[OPT_FOCUS].cap &= ~SANE_CAP_INACTIVE;
631 	    }
632 	  return (SANE_STATUS_GOOD);
633 
634 	case OPT_FLATBED_ONLY:
635 	  s->val[option].w = *(SANE_Word *) val;
636 	  if (s->hw->adf.Status != ADF_STAT_NONE && s->val[option].w)
637 	    {					/* switch on */
638 	      s->hw->adf.Priority |= 0x03;	/* flatbed mode */
639 	      s->hw->adf.Feeder &= 0x00;	/* autofeed off (default) */
640 	      s->hw->adf.Status = ADF_STAT_DISABLED;
641 	    }		/* if it isn't connected, don't bother fixing */
642 	  return SANE_STATUS_GOOD;
643 
644 	case OPT_TPU_ON:
645 	  s->val[option].w = *(SANE_Word *) val;
646 	  if (s->val[option].w)			/* switch on */
647 	    {
648 	      s->hw->tpu.Status = TPU_STAT_ACTIVE;
649 	      s->opt[OPT_TPU_TRANSPARENCY].cap &=
650 		(s->hw->tpu.ControlMode == 3) ? ~SANE_CAP_INACTIVE : ~0;
651 	      s->opt[OPT_TPU_FILMTYPE].cap &=
652 		(s->hw->tpu.ControlMode == 1) ? ~SANE_CAP_INACTIVE : ~0;
653 	    }
654 	  else			/* switch off */
655 	    {
656 	      s->hw->tpu.Status = TPU_STAT_INACTIVE;
657 	      s->opt[OPT_TPU_TRANSPARENCY].cap |= SANE_CAP_INACTIVE;
658 	      s->opt[OPT_TPU_FILMTYPE].cap |= SANE_CAP_INACTIVE;
659 	    }
660 	  s->opt[OPT_TPU_PN].cap ^= SANE_CAP_INACTIVE;
661 	  s->opt[OPT_TPU_DCM].cap ^= SANE_CAP_INACTIVE;
662           if (info)
663 	    *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
664 	  return SANE_STATUS_GOOD;
665 
666 	case OPT_TPU_DCM:
667 	  if (s->val[OPT_TPU_DCM].s)
668 	    free (s->val[OPT_TPU_DCM].s);
669 	  s->val[OPT_TPU_DCM].s = strdup (val);
670 
671 	  s->opt[OPT_TPU_TRANSPARENCY].cap |= SANE_CAP_INACTIVE;
672 	  s->opt[OPT_TPU_FILMTYPE].cap |= SANE_CAP_INACTIVE;
673 	  if (!strcmp (s->val[OPT_TPU_DCM].s,
674 	  SANE_I18N("Correction according to transparency ratio")))
675 	    {
676 	      s->hw->tpu.ControlMode = 3;
677 	      s->opt[OPT_TPU_TRANSPARENCY].cap &= ~SANE_CAP_INACTIVE;
678 	    }
679 	  else if (!strcmp (s->val[OPT_TPU_DCM].s,
680 	  SANE_I18N("Correction according to film type")))
681 	    {
682 	      s->hw->tpu.ControlMode = 1;
683 	      s->opt[OPT_TPU_FILMTYPE].cap &= ~SANE_CAP_INACTIVE;
684 	    }
685 	  else
686 	    s->hw->tpu.ControlMode = 0;
687           if (info)
688 	    *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
689 	  return SANE_STATUS_GOOD;
690 
691 	case OPT_TPU_FILMTYPE:
692 	  if (s->val[option].s)
693 	    free (s->val[option].s);
694 	  s->val[option].s = strdup (val);
695 	  return SANE_STATUS_GOOD;
696 
697 	case OPT_MODE:
698 	  if (info && strcmp (s->val[option].s, (SANE_String) val))
699 	    *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
700 	  if (s->val[option].s)
701 	    free (s->val[option].s);
702 	  s->val[option].s = strdup (val);
703 	  if (!strcmp (val, SANE_VALUE_SCAN_MODE_LINEART)
704 	  || !strcmp (val, SANE_VALUE_SCAN_MODE_HALFTONE))
705 	    {
706 	      /* For Lineart and Halftone: */
707 	      /* Enable "threshold" */
708 	      s->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
709 
710 	      /* Disable "custom gamma" and "brightness & contrast" */
711 	      s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE;
712 	      s->opt[OPT_CUSTOM_GAMMA_BIND].cap |= SANE_CAP_INACTIVE;
713 	      s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
714 	      s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
715 	      s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
716 	      s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
717 
718 	      s->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
719 	      s->opt[OPT_CONTRAST].cap |= SANE_CAP_INACTIVE;
720 	    }
721 	  else
722 	    {
723 	      /* For Gray and Color modes: */
724 	      /* Disable "threshold" */
725 	      s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
726 
727 	      /* Enable "custom gamma" and "brightness & contrast" */
728 	      s->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE;
729 	      if (s->val[OPT_CUSTOM_GAMMA].w)
730 		{
731 		  if (!strcmp (val, SANE_VALUE_SCAN_MODE_COLOR)
732 		  || !strcmp (val, SANE_I18N("Fine color")))
733 		    {
734 		      s->opt[OPT_CUSTOM_GAMMA_BIND].cap &= ~SANE_CAP_INACTIVE;
735 		      if (s->val[OPT_CUSTOM_GAMMA_BIND].w == SANE_TRUE)
736 			{
737 			  s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
738 			  s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
739 			  s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
740 			  s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
741 			}
742 		      else
743 			{
744 			  s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
745 			  s->opt[OPT_GAMMA_VECTOR_R].cap &=
746 			    ~SANE_CAP_INACTIVE;
747 			  s->opt[OPT_GAMMA_VECTOR_G].cap &=
748 			    ~SANE_CAP_INACTIVE;
749 			  s->opt[OPT_GAMMA_VECTOR_B].cap &=
750 			    ~SANE_CAP_INACTIVE;
751 			}
752 		    }
753 		  else
754 		    {
755 		      s->opt[OPT_CUSTOM_GAMMA_BIND].cap |= SANE_CAP_INACTIVE;
756 		      s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
757 		      s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
758 		      s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
759 		      s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
760 		    }
761 		}
762 	      else
763 		{
764 		  s->opt[OPT_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
765 		  s->opt[OPT_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
766 		}
767 	    }
768 	  return (SANE_STATUS_GOOD);
769 
770 	case OPT_NEGATIVE:
771 	  if (info && strcmp (s->val[option].s, (SANE_String) val))
772 	    *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
773 	  if (s->val[option].s)
774 	    free (s->val[option].s);
775 	  s->val[option].s = strdup (val);
776 	  if (!strcmp (val, SANE_I18N("Negatives")))
777 	    {
778 	      s->RIF = 0;
779 	      s->opt[OPT_NEGATIVE_TYPE].cap &= ~SANE_CAP_INACTIVE;
780 	      if (SANE_OPTION_IS_SETTABLE(s->opt[OPT_SCANNING_SPEED].cap))
781 		s->opt[OPT_SCANNING_SPEED].cap &= ~SANE_CAP_INACTIVE;
782 	    }
783 	  else
784 	    {
785 	      s->RIF = 1;
786 	      s->opt[OPT_NEGATIVE_TYPE].cap |= SANE_CAP_INACTIVE;
787 	      s->opt[OPT_SCANNING_SPEED].cap |= SANE_CAP_INACTIVE;
788 	    }
789 	  return (SANE_STATUS_GOOD);
790 
791 	case OPT_NEGATIVE_TYPE:
792 	  if (info && strcmp (s->val[option].s, (SANE_String) val))
793 	    *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
794 	  if (s->val[option].s)
795 	    free (s->val[option].s);
796 	  s->val[option].s = strdup (val);
797 	  for (i = 0; strcmp (val, negative_filmtype_list[i]); i++);
798 	  s->negative_filmtype = i;
799 	  return (SANE_STATUS_GOOD);
800 
801 	case OPT_SCANNING_SPEED:
802 	  if (info && strcmp (s->val[option].s, (SANE_String) val))
803 	    *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
804 	  if (s->val[option].s)
805 	    free (s->val[option].s);
806 	  s->val[option].s = strdup (val);
807 	  for (i = 0; strcmp (val, scanning_speed_list[i]); i++);
808 	  s->scanning_speed = i;
809 	  return (SANE_STATUS_GOOD);
810 
811 	  /* modification for FB620S */
812 	case OPT_CALIBRATION_NOW:
813 	  sanei_scsi_open (s->hw->sane.name, &s->fd, sense_handler, s->hw);
814 	  if (status == SANE_STATUS_GOOD)
815 	    {
816 	      status = execute_calibration (s->fd);
817 	      if (status != SANE_STATUS_GOOD)
818 		{
819 		  DBG (21, "EXECUTE CALIBRATION failed\n");
820 		  sanei_scsi_close (s->fd);
821 		  s->fd = -1;
822 		  return (SANE_STATUS_INVAL);
823 		}
824 	      DBG (21, "EXECUTE CALIBRATION\n");
825 	      sanei_scsi_close (s->fd);
826 	    }
827 	  else
828 	    DBG (1, "calibration: cannot open device file\n");
829 	  s->fd = -1;
830 	  return status;
831 
832 	case OPT_SCANNER_SELF_DIAGNOSTIC:
833 	  sanei_scsi_open (s->hw->sane.name, &s->fd, sense_handler, s->hw);
834 	  if (status == SANE_STATUS_GOOD)
835 	    {
836 	      status = send_diagnostic (s->fd);
837 	      {
838 		if (status != SANE_STATUS_GOOD)
839 		  {
840 		    DBG (21, "SEND DIAGNOSTIC error: %s\n",
841 			 sane_strstatus (status));
842 		    sanei_scsi_close (s->fd);
843 		    s->fd = -1;
844 		    return (status);
845 		  }
846 		DBG (21, "SEND DIAGNOSTIC result: %s\n",
847 		  sane_strstatus (status));
848 		sanei_scsi_close (s->fd);
849 	      }
850 	    }
851 	  else
852 	    DBG (1, "send diagnostic: cannot open device file\n");
853 	  s->fd = -1;
854 	  return status;
855 
856 	case OPT_RESET_SCANNER:
857 	  sanei_scsi_open (s->hw->sane.name, &s->fd, sense_handler, s->hw);
858 	  if (status == SANE_STATUS_GOOD)
859 	    {
860 	      time (&(s->time1));
861 	      DBG (11, "time0 = %ld\n", s->time0);
862 	      DBG (11, "time1 = %ld\n", s->time1);
863 	      dtime = (s->time1) - (s->time0);
864 	      DBG (11, "dtime = %ld\n", dtime);
865 
866 	      DBG (11, "switch_preview = %d\n", s->switch_preview);
867 	      if (s->switch_preview == 0)
868 		{
869 		  rt = sqrt (15 * 15 * (SANE_UNFIX (s->val[OPT_BR_Y].w))
870 		    / 297) + 0.5;
871 		  rt = rt + 2;
872 		}
873 	      else
874 		rt = 17;
875 
876 	      DBG (11, "SANE_UNFIX(s->val[OPT_BR_Y].w) = %f\n",
877 		   SANE_UNFIX (s->val[OPT_BR_Y].w));
878 	      DBG (11, "rt = %ld\n", rt);
879 
880 	      if (dtime < rt)
881 		{
882 		  int_t = (int) (rt - dtime);
883 		  DBG (11, "int_t = %d\n", int_t);
884 
885 		  sleep (int_t);
886 		}
887 	      status = reset_scanner (s->fd);
888 	      {
889 		if (status != SANE_STATUS_GOOD)
890 		  {
891 		    DBG (21, "RESET SCANNER failed\n");
892 		    sanei_scsi_close (s->fd);
893 		    s->fd = -1;
894 		    return (status);
895 		  }
896 
897 		DBG (21, "RESET SCANNER\n");
898 		sanei_scsi_close (s->fd);
899 	      }
900 	    }
901 	  else
902 	    DBG (1, "reset scanner: cannot open device file\n");
903 	  s->fd = -1;
904 	  return status;
905 
906 	case OPT_EJECT_NOW:
907 	  sanei_scsi_open (s->hw->sane.name, &s->fd, sense_handler, s->hw);
908 	  status = medium_position (s->fd);
909 	  if (status != SANE_STATUS_GOOD)
910 	    {
911 	      DBG (21, "MEDIUM POSITION failed\n");
912 	      sanei_scsi_close (s->fd);
913 	      s->fd = -1;
914 	      return (SANE_STATUS_INVAL);
915 	    }
916 	  DBG (21, "AF_NOW before = '%d'\n", s->AF_NOW);
917 	  s->AF_NOW = SANE_TRUE;
918 	  DBG (21, "AF_NOW after = '%d'\n", s->AF_NOW);
919 	  sanei_scsi_close (s->fd);
920 	  s->fd = -1;
921 	  return status;
922 
923 	case OPT_CUSTOM_GAMMA:
924 	  w = *(SANE_Word *) val;
925 
926 	  if (w == s->val[OPT_CUSTOM_GAMMA].w)
927 	    return SANE_STATUS_GOOD;	/* no change */
928 
929 	  if (info)
930 	    *info |= SANE_INFO_RELOAD_OPTIONS;
931 
932 	  s->val[OPT_CUSTOM_GAMMA].w = w;
933 	  if (w)
934 	    {
935 	      const char *mode = s->val[OPT_MODE].s;
936 
937 	      if (!strcmp (mode, SANE_VALUE_SCAN_MODE_GRAY))
938 		s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
939 	      else if (!strcmp (mode, SANE_VALUE_SCAN_MODE_COLOR)
940 	      || !strcmp (mode, SANE_I18N("Fine color")))
941 		{
942 		  s->opt[OPT_CUSTOM_GAMMA_BIND].cap &= ~SANE_CAP_INACTIVE;
943 		  if (s->val[OPT_CUSTOM_GAMMA_BIND].w)
944 		    {
945 		      s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
946 		      s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
947 		      s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
948 		      s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
949 		    }
950 		  else
951 		    {
952 		      s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
953 		      s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
954 		      s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
955 		      s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
956 		    }
957 		}
958 	      s->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
959 	      s->opt[OPT_CONTRAST].cap |= SANE_CAP_INACTIVE;
960 	    }
961 	  else
962 	    {
963 	      s->opt[OPT_CUSTOM_GAMMA_BIND].cap |= SANE_CAP_INACTIVE;
964 	      s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
965 	      s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
966 	      s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
967 	      s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
968 
969 	      s->opt[OPT_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
970 	      s->opt[OPT_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
971 	    }
972 
973 	  return SANE_STATUS_GOOD;
974 
975 	case OPT_CUSTOM_GAMMA_BIND:
976 	  w = *(SANE_Word *) val;
977 
978 	  if (w == s->val[OPT_CUSTOM_GAMMA_BIND].w)
979 	    return SANE_STATUS_GOOD;	/* no change */
980 
981 	  if (info)
982 	    *info |= SANE_INFO_RELOAD_OPTIONS;
983 
984 	  s->val[OPT_CUSTOM_GAMMA_BIND].w = w;
985 	  if (w)
986 	    {
987 	      s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
988 	      s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
989 	      s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
990 	      s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
991 	    }
992 	  else
993 	    {
994 	      s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
995 	      s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
996 	      s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
997 	      s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
998 	    }
999 
1000 	  return SANE_STATUS_GOOD;
1001 
1002 	case OPT_GAMMA_VECTOR:
1003 	case OPT_GAMMA_VECTOR_R:
1004 	case OPT_GAMMA_VECTOR_G:
1005 	case OPT_GAMMA_VECTOR_B:
1006 	  memcpy (s->val[option].wa, val, s->opt[option].size);
1007 	  DBG (21, "setting gamma vector\n");
1008 /*       if (info) */
1009 /* 	*info |= SANE_INFO_RELOAD_OPTIONS; */
1010 	  return (SANE_STATUS_GOOD);
1011 
1012 	}
1013     }
1014 
1015   DBG (1, "<< sane_control_option %s\n", option_name[option]);
1016   return (SANE_STATUS_INVAL);
1017 
1018 }
1019 
1020 /**************************************************************************/
1021 
1022 SANE_Status
sane_get_parameters(SANE_Handle handle,SANE_Parameters * params)1023 sane_get_parameters (SANE_Handle handle, SANE_Parameters *params)
1024 {
1025   CANON_Scanner *s = handle;
1026   DBG (1, ">> sane_get_parameters\n");
1027 
1028   if (!s->scanning)
1029     {
1030       int width, length, xres, yres;
1031       const char *mode;
1032 
1033       memset (&s->params, 0, sizeof (s->params));
1034 
1035       width = SANE_UNFIX (s->val[OPT_BR_X].w - s->val[OPT_TL_X].w)
1036 	* s->hw->info.mud / MM_PER_INCH;
1037       length = SANE_UNFIX (s->val[OPT_BR_Y].w - s->val[OPT_TL_Y].w)
1038 	* s->hw->info.mud / MM_PER_INCH;
1039 
1040       xres = s->val[OPT_X_RESOLUTION].w;
1041       yres = s->val[OPT_Y_RESOLUTION].w;
1042       if (s->val[OPT_RESOLUTION_BIND].w || s->val[OPT_PREVIEW].w)
1043 	yres = xres;
1044 
1045       /* make best-effort guess at what parameters will look like once
1046          scanning starts.  */
1047       if (xres > 0 && yres > 0 && width > 0 && length > 0)
1048 	{
1049 	  DBG (11, "sane_get_parameters: width='%d', xres='%d', mud='%d'\n",
1050 	       width, xres, s->hw->info.mud);
1051 	  s->params.pixels_per_line = width * xres / s->hw->info.mud;
1052 	  DBG (11, "sane_get_parameters: length='%d', yres='%d', mud='%d'\n",
1053 	       length, yres, s->hw->info.mud);
1054 	  s->params.lines = length * yres / s->hw->info.mud;
1055 	  DBG (11, "sane_get_parameters: pixels_per_line='%d', lines='%d'\n",
1056 	       s->params.pixels_per_line, s->params.lines);
1057 	}
1058 
1059       mode = s->val[OPT_MODE].s;
1060       if (!strcmp (mode, SANE_VALUE_SCAN_MODE_LINEART)
1061       || !strcmp (mode, SANE_VALUE_SCAN_MODE_HALFTONE))
1062 	{
1063 	  s->params.format = SANE_FRAME_GRAY;
1064 	  s->params.bytes_per_line = s->params.pixels_per_line / 8;
1065 	  /* workaround rounding problems */
1066 	  s->params.pixels_per_line = s->params.bytes_per_line * 8;
1067 	  s->params.depth = 1;
1068 	}
1069       else if (!strcmp (mode, SANE_VALUE_SCAN_MODE_GRAY))
1070 	{
1071 	  s->params.format = SANE_FRAME_GRAY;
1072 	  s->params.bytes_per_line = s->params.pixels_per_line;
1073 	  s->params.depth = 8;
1074 	}
1075       else if (!strcmp (mode, SANE_VALUE_SCAN_MODE_COLOR)
1076       || !strcmp (mode, SANE_I18N("Fine color")))
1077 	{
1078 	  s->params.format = SANE_FRAME_RGB;
1079 	  s->params.bytes_per_line = 3 * s->params.pixels_per_line;
1080 	  s->params.depth = 8;
1081 	}
1082       else
1083 	{
1084 	  s->params.format = SANE_FRAME_RGB;
1085 	  s->params.bytes_per_line = 6 * s->params.pixels_per_line;
1086 	  s->params.depth = 16;
1087 	}
1088       s->params.last_frame = SANE_TRUE;
1089     }
1090 
1091   DBG (11, "sane_get_parameters: xres='%d', yres='%d', pixels_per_line='%d', "
1092     "bytes_per_line='%d', lines='%d'\n", s->xres, s->yres,
1093     s->params.pixels_per_line, s->params.bytes_per_line, s->params.lines);
1094 
1095   if (params)
1096     *params = s->params;
1097 
1098   DBG (1, "<< sane_get_parameters\n");
1099   return (SANE_STATUS_GOOD);
1100 }
1101 
1102 /**************************************************************************/
1103 
1104 SANE_Status
sane_start(SANE_Handle handle)1105 sane_start (SANE_Handle handle)
1106 {
1107   char *mode_str;
1108   CANON_Scanner *s = handle;
1109   SANE_Status status;
1110   u_char wbuf[72], dbuf[28], ebuf[72];
1111   u_char cbuf[2];			/* modification for FB620S */
1112   size_t buf_size, i;
1113 
1114   char tmpfilename[] = "/tmp/canon.XXXXXX"; /* for FB1200S */
1115   char *thistmpfile; /* for FB1200S */
1116 
1117   DBG (1, ">> sane_start\n");
1118 
1119   s->tmpfile = -1; /* for FB1200S */
1120 
1121 /******* making a tempfile for 1200 dpi scanning of FB1200S ******/
1122   if (s->hw->info.model == FB1200)
1123     {
1124       thistmpfile = strdup(tmpfilename);
1125 
1126       if (thistmpfile != NULL)
1127         {
1128           if (!mkstemp(thistmpfile))
1129             {
1130               DBG(1, "mkstemp(thistmpfile) is failed\n");
1131               return (SANE_STATUS_INVAL);
1132 	    }
1133 	}
1134       else
1135         {
1136 	  DBG(1, "strdup(thistmpfile) is failed\n");
1137 	  return (SANE_STATUS_INVAL);
1138 	}
1139 
1140       s->tmpfile = open(thistmpfile, O_RDWR | O_CREAT | O_EXCL, 0600);
1141 
1142       if (s->tmpfile == -1)
1143 	{
1144 	  DBG(1, "error opening temp file %s\n", thistmpfile);
1145 	  DBG(1, "errno: %i; %s\n", errno, strerror(errno));
1146 	  errno = 0;
1147 	  return (SANE_STATUS_INVAL);
1148 	}
1149       DBG(1, " ****** tmpfile is opened ****** \n");
1150 
1151       unlink(thistmpfile);
1152       free (thistmpfile);
1153       DBG(1, "free thistmpfile\n");
1154     }
1155 /******************************************************************/
1156 
1157   s->scanning = SANE_FALSE;
1158 
1159   if ((s->hw->adf.Status != ADF_STAT_NONE)
1160       && (s->val[OPT_FLATBED_ONLY].w != SANE_TRUE)
1161       && (s->hw->adf.Problem != 0))
1162     {
1163       DBG (3, "SCANNER ADF HAS A PROBLEM\n");
1164       if (s->hw->adf.Problem & 0x08)
1165 	{
1166 	  status = SANE_STATUS_COVER_OPEN;
1167 	  DBG (3, "ADF Cover Open\n");
1168 	}
1169       else if (s->hw->adf.Problem & 0x04)
1170 	{
1171 	  status = SANE_STATUS_JAMMED;
1172 	  DBG (3, "ADF Paper Jam\n");
1173 	}
1174       else			/* adf.Problem = 0x02 */
1175 	{
1176 	  status = SANE_STATUS_NO_DOCS;
1177 	  DBG (3, "ADF No More Documents\n");
1178 	}
1179       return status;
1180     }
1181   else if ((s->hw->adf.Status != ADF_STAT_NONE)
1182 	   && (s->val[OPT_FLATBED_ONLY].w == SANE_TRUE))
1183     {
1184       set_adf_mode (s->fd, s->hw->adf.Priority);
1185       /* 2.23 define ADF Mode */
1186     }
1187 
1188   /* First make sure we have a current parameter set.  Some of the
1189      parameters will be overwritten below, but that's OK.  */
1190   status = sane_get_parameters (s, 0);
1191   if (status != SANE_STATUS_GOOD)
1192     return status;
1193 
1194   status = sanei_scsi_open (s->hw->sane.name, &s->fd, sense_handler, s->hw);
1195   if (status != SANE_STATUS_GOOD)
1196     {
1197       DBG (1, "open of %s failed: %s\n", s->hw->sane.name,
1198 	sane_strstatus (status));
1199       return (status);
1200     }
1201 
1202 #if 0				/* code moved after define_scan() calls */
1203   /* Do focus, but not for the preview */
1204   if (SANE_OPTION_IS_ACTIVE(s->opt[OPT_FOCUS_GROUP].cap)
1205     && !s->val[OPT_PREVIEW].w && s->AF_NOW)
1206     {
1207       if ((status = do_focus (s)) != SANE_STATUS_GOOD) return (status);
1208       if (s->val[OPT_AF_ONCE].w) s->AF_NOW = SANE_FALSE;
1209     }
1210 #endif
1211 
1212   if (s->val[OPT_CUSTOM_GAMMA].w)
1213     {
1214       if ((status = do_gamma (s)) != SANE_STATUS_GOOD) return (status);
1215     }
1216 
1217   DBG (3, "attach: sending GET SCAN MODE for scan control conditions\n");
1218   memset (ebuf, 0, sizeof (ebuf));
1219   buf_size = 20;
1220   status = get_scan_mode (s->fd, (u_char) SCAN_CONTROL_CONDITIONS,
1221     ebuf, &buf_size);
1222   if (status != SANE_STATUS_GOOD)
1223     {
1224       DBG (1, "attach: GET SCAN MODE for scan control conditions failed\n");
1225       sanei_scsi_close (s->fd);
1226       return (SANE_STATUS_INVAL);
1227     }
1228   for (i = 0; i < buf_size; i++)
1229     DBG (3, "scan mode control byte[%d] = %d\n", (int) i, ebuf[i]);
1230 
1231   if (s->hw->adf.Status != ADF_STAT_NONE)
1232     {
1233       DBG (3, "attach: sending GET SCAN MODE for transparency unit\n");
1234       memset (ebuf, 0, sizeof (ebuf));
1235       buf_size = 12;
1236       status = get_scan_mode (s->fd, (u_char) TRANSPARENCY_UNIT,
1237 			      ebuf, &buf_size);
1238       if (status != SANE_STATUS_GOOD)
1239 	{
1240 	  DBG (1, "attach: GET SCAN MODE for transparency unit failed\n");
1241 	  sanei_scsi_close (s->fd);
1242 	  return (SANE_STATUS_INVAL);
1243 	}
1244       for (i = 0; i < buf_size; i++)
1245 	DBG (3, "scan mode control byte[%d] = %d\n", (int) i,
1246 	ebuf[i]);
1247     }
1248 
1249   mode_str = s->val[OPT_MODE].s;
1250   s->xres = s->val[OPT_X_RESOLUTION].w;
1251   s->yres = s->val[OPT_Y_RESOLUTION].w;
1252 
1253   if (s->val[OPT_RESOLUTION_BIND].w || s->val[OPT_PREVIEW].w)
1254       s->yres = s->xres;
1255 
1256   s->ulx = SANE_UNFIX (s->val[OPT_TL_X].w) * s->hw->info.mud / MM_PER_INCH;
1257   s->uly = SANE_UNFIX (s->val[OPT_TL_Y].w) * s->hw->info.mud / MM_PER_INCH;
1258 
1259   s->width = SANE_UNFIX (s->val[OPT_BR_X].w - s->val[OPT_TL_X].w)
1260     * s->hw->info.mud / MM_PER_INCH;
1261   s->length = SANE_UNFIX (s->val[OPT_BR_Y].w - s->val[OPT_TL_Y].w)
1262     * s->hw->info.mud / MM_PER_INCH;
1263 
1264   DBG (11, "s->width='%d', s->length='%d'\n", s->width, s->length);
1265 
1266   if (s->hw->info.model != CS2700 && s->hw->info.model != FS2710)
1267     {
1268       if (!strcmp (mode_str, SANE_VALUE_SCAN_MODE_LINEART)
1269       || !strcmp (mode_str, SANE_VALUE_SCAN_MODE_HALFTONE))
1270 	s->RIF = s->val[OPT_HNEGATIVE].w;
1271       else
1272 	s->RIF = !s->val[OPT_HNEGATIVE].w;
1273     }
1274 
1275   s->brightness = s->val[OPT_BRIGHTNESS].w;
1276   s->contrast = s->val[OPT_CONTRAST].w;
1277   s->threshold = s->val[OPT_THRESHOLD].w;
1278   s->bpp = s->params.depth;
1279 
1280   s->GRC = s->val[OPT_CUSTOM_GAMMA].w;
1281   s->Mirror = s->val[OPT_MIRROR].w;
1282   s->AE = s->val[OPT_AE].w;
1283 
1284   s->HiliteG = s->val[OPT_HILITE_G].w;
1285   s->ShadowG = s->val[OPT_SHADOW_G].w;
1286   if (s->val[OPT_BIND_HILO].w)
1287     {
1288       s->HiliteR = s->val[OPT_HILITE_G].w;
1289       s->ShadowR = s->val[OPT_SHADOW_G].w;
1290       s->HiliteB = s->val[OPT_HILITE_G].w;
1291       s->ShadowB = s->val[OPT_SHADOW_G].w;
1292     }
1293   else
1294     {
1295       s->HiliteR = s->val[OPT_HILITE_R].w;
1296       s->ShadowR = s->val[OPT_SHADOW_R].w;
1297       s->HiliteB = s->val[OPT_HILITE_B].w;
1298       s->ShadowB = s->val[OPT_SHADOW_B].w;
1299     }
1300 
1301   if (!strcmp (mode_str, SANE_VALUE_SCAN_MODE_LINEART))
1302     {
1303       s->image_composition = 0;
1304     }
1305   else if (!strcmp (mode_str, SANE_VALUE_SCAN_MODE_HALFTONE))
1306     {
1307       s->image_composition = 1;
1308     }
1309   else if (!strcmp (mode_str, SANE_VALUE_SCAN_MODE_GRAY))
1310     {
1311       s->image_composition = 2;
1312     }
1313   else if (!strcmp (mode_str, SANE_VALUE_SCAN_MODE_COLOR)
1314   || !strcmp (mode_str, SANE_I18N("Fine color")))
1315     {
1316       s->image_composition = 5;
1317     }
1318   else if (!strcmp (mode_str, SANE_I18N("Raw")))
1319     {
1320       s->image_composition = 5;
1321     }
1322   else
1323     {
1324       s->image_composition = 5;
1325     }
1326 
1327   memset (wbuf, 0, sizeof (wbuf));
1328   wbuf[7] = 64;
1329   wbuf[10] = s->xres >> 8;
1330   wbuf[11] = s->xres;
1331   wbuf[12] = s->yres >> 8;
1332   wbuf[13] = s->yres;
1333   wbuf[14] = s->ulx >> 24;
1334   wbuf[15] = s->ulx >> 16;
1335   wbuf[16] = s->ulx >> 8;
1336   wbuf[17] = s->ulx;
1337   wbuf[18] = s->uly >> 24;
1338   wbuf[19] = s->uly >> 16;
1339   wbuf[20] = s->uly >> 8;
1340   wbuf[21] = s->uly;
1341   wbuf[22] = s->width >> 24;
1342   wbuf[23] = s->width >> 16;
1343   wbuf[24] = s->width >> 8;
1344   wbuf[25] = s->width;
1345   wbuf[26] = s->length >> 24;
1346   wbuf[27] = s->length >> 16;
1347   wbuf[28] = s->length >> 8;
1348   wbuf[29] = s->length;
1349   wbuf[30] = s->brightness;
1350   wbuf[31] = s->threshold;
1351   wbuf[32] = s->contrast;
1352   wbuf[33] = s->image_composition;
1353   wbuf[34] = (s->hw->info.model == FS2710) ? 12 : s->bpp;
1354   wbuf[36] = 1;
1355   wbuf[37] = (1 << 7) + 0x03;
1356   wbuf[50] = (s->GRC << 3) | (s->Mirror << 2);
1357 #if 1
1358    wbuf[50] |= s->AE;	/* AE also for preview; needed by frontend controls */
1359 #else
1360   if (!s->val[OPT_PREVIEW].w) wbuf[50] |= s->AE; /* AE not during preview */
1361 #endif
1362   wbuf[54] = 2;
1363   wbuf[57] = 1;
1364   wbuf[58] = 1;
1365   wbuf[59] = s->HiliteR;
1366   wbuf[60] = s->ShadowR;
1367   wbuf[62] = s->HiliteG;
1368   wbuf[64] = s->ShadowG;
1369   wbuf[70] = s->HiliteB;
1370   wbuf[71] = s->ShadowB;
1371 
1372   DBG (7, "RIF=%d, GRC=%d, Mirror=%d, AE=%d, Speed=%d\n", s->RIF, s->GRC,
1373     s->Mirror, s->AE, s->scanning_speed);
1374   DBG (7, "HR=%d, SR=%d, HG=%d, SG=%d, HB=%d, SB=%d\n", s->HiliteR,
1375     s->ShadowR, s->HiliteG, s->ShadowG, s->HiliteB, s->ShadowB);
1376 
1377   if (s->hw->info.model == FB620)	/* modification for FB620S */
1378     {
1379       wbuf[36] = 0;
1380       wbuf[37] = (s->RIF << 7) + 0x3;
1381       wbuf[50] = s->GRC << 3;
1382       wbuf[54] = 0;
1383       wbuf[57] = 0;
1384       wbuf[58] = 0;
1385     }
1386   else if (s->hw->info.model == FB1200)	/* modification for FB1200S */
1387     {
1388 #if 0
1389       wbuf[34] = (((600 < s->val[OPT_X_RESOLUTION].w)
1390 	|| (600 < s->val[OPT_Y_RESOLUTION].w))
1391 	&& (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART) != 0))
1392 	? 12 : s->bpp;
1393 #endif
1394       wbuf[36] = 0;
1395       wbuf[37] = (s->RIF << 7) + 0x3;
1396       wbuf[50] = (1 << 4) | (s->GRC << 3);
1397       wbuf[57] = 1;
1398       wbuf[58] = 1;
1399     }
1400   else if (s->hw->info.model == IX4015) /* modification for IX-4015 */
1401     {
1402       wbuf[36] = 0;
1403       wbuf[37] = (s->RIF << 7);
1404       wbuf[57] = 0;
1405       wbuf[58] = 0;
1406       /* no highlight and shadow control */
1407       wbuf[59] = 0;
1408       wbuf[60] = 0;
1409       wbuf[62] = 0;
1410       wbuf[64] = 0;
1411       wbuf[70] = 0;
1412       wbuf[71] = 0;
1413     }
1414 
1415   buf_size = sizeof (wbuf);
1416   status = set_window (s->fd, wbuf);
1417   if (status != SANE_STATUS_GOOD)
1418     {
1419       DBG (1, "SET WINDOW failed: %s\n", sane_strstatus (status));
1420       return (status);
1421     }
1422   if (s->hw->info.model == FS2710)
1423     status = set_parameters_fs2710 (s);
1424   buf_size = sizeof (wbuf);
1425   memset (wbuf, 0, buf_size);
1426   status = get_window (s->fd, wbuf, &buf_size);
1427   if (status != SANE_STATUS_GOOD)
1428     {
1429       DBG (1, "GET WINDOW failed: %s\n", sane_strstatus (status));
1430       return (status);
1431     }
1432   DBG (5, "xres=%d\n", (wbuf[10] << 8) + wbuf[11]);
1433   DBG (5, "yres=%d\n", (wbuf[12] << 8) + wbuf[13]);
1434   DBG (5, "ulx=%d\n", (wbuf[14] << 24) + (wbuf[15] << 16) + (wbuf[16] << 8)
1435     + wbuf[17]);
1436   DBG (5, "uly=%d\n", (wbuf[18] << 24) + (wbuf[19] << 16) + (wbuf[20] << 8)
1437     + wbuf[21]);
1438   DBG (5, "width=%d\n", (wbuf[22] << 24) + (wbuf[23] << 16) + (wbuf[24] << 8)
1439     + wbuf[25]);
1440   DBG (5, "length=%d\n", (wbuf[26] << 24) + (wbuf[27] << 16) + (wbuf[28] << 8)
1441     + wbuf[29]);
1442   DBG (5, "Highlight Red=%d\n", wbuf[59]);
1443   DBG (5, "Shadow Red=%d\n", wbuf[60]);
1444   DBG (5, "Highlight (Green)=%d\n", wbuf[62]);
1445   DBG (5, "Shadow (Green)=%d\n", wbuf[64]);
1446   DBG (5, "Highlight Blue=%d\n", wbuf[70]);
1447   DBG (5, "Shadow Blue=%d\n", wbuf[71]);
1448 
1449   if (s->hw->tpu.Status == TPU_STAT_ACTIVE || s->hw->info.is_filmscanner)
1450     {
1451       DBG (3, "sane_start: sending DEFINE SCAN MODE for transparency unit, "
1452 	"NP=%d, Negative film type=%d\n", !s->RIF, s->negative_filmtype);
1453       memset (wbuf, 0, sizeof (wbuf));
1454       wbuf[0] = 0x02;
1455       wbuf[1] = 6;
1456       wbuf[2] = 0x80;
1457       wbuf[3] = 0x05;
1458       wbuf[4] = 39;
1459       wbuf[5] = 16;
1460       wbuf[6] = !s->RIF;
1461       wbuf[7] = s->negative_filmtype;
1462       status = define_scan_mode (s->fd, TRANSPARENCY_UNIT, wbuf);
1463       /* note: If we implement a TPU for the FB1200S, we need
1464          TRANSPARENCY_UNIT_FB1200 here. */
1465       if (status != SANE_STATUS_GOOD)
1466 	{
1467 	  DBG (1, "define scan mode failed: %s\n", sane_strstatus (status));
1468 	  return (status);
1469 	}
1470     }
1471 
1472   DBG (3, "sane_start: sending DEFINE SCAN MODE for scan control "
1473     "conditions\n");
1474   memset (wbuf, 0, sizeof (wbuf));
1475   wbuf[0] = 0x20;
1476   if (s->hw->info.model == FB1200)
1477     {
1478       wbuf[1] = 17;
1479       wbuf[16] = 3;
1480       wbuf[17] = 8;
1481       wbuf[18] = (1 << 7) | (1 << 3);
1482 
1483       DBG (3, "sane_start: sending DEFINE SCAN MODE for scan control "
1484 	"conditions of FB1200\n");
1485       status = define_scan_mode (s->fd, SCAN_CONTROL_CON_FB1200, wbuf);
1486     }
1487   else
1488     {
1489       wbuf[1] = 14;
1490       /* For preview use always normal speed: */
1491       if (!s->val[OPT_PREVIEW].w && s->hw->info.is_filmscanner)
1492 	wbuf[11] = s->scanning_speed;
1493       wbuf[15] = (s->hw->info.model == FB620
1494 	&& !strcmp (mode_str, SANE_I18N("Fine color"))
1495 	&& !s->val[OPT_PREVIEW].w) ? 1 << 3 : 0;
1496       status = define_scan_mode (s->fd, SCAN_CONTROL_CONDITIONS, wbuf);
1497     }
1498   if (status != SANE_STATUS_GOOD)
1499     {
1500       DBG (1, "define scan mode failed: %s\n", sane_strstatus (status));
1501       return (status);
1502     }
1503 
1504   DBG (3, "sane_start: sending GET SCAN MODE for scan control conditions\n");
1505   memset (ebuf, 0, sizeof (ebuf));
1506   buf_size = sizeof (ebuf);
1507   status = get_scan_mode (s->fd, SCAN_CONTROL_CONDITIONS, ebuf, &buf_size);
1508   if (status != SANE_STATUS_GOOD)
1509     {
1510       DBG (1, "sane_start: GET SCAN MODE for scan control conditions "
1511 	"failed\n");
1512       sanei_scsi_close (s->fd);
1513       return (SANE_STATUS_INVAL);
1514     }
1515   for (i = 0; i < buf_size; i++)
1516     DBG (3, "scan mode byte[%d] = %d\n", (int) i, ebuf[i]);
1517 
1518   /* Focus, but not for previews or negatives with speed control */
1519   if (SANE_OPTION_IS_ACTIVE(s->opt[OPT_FOCUS_GROUP].cap)
1520     && !s->val[OPT_PREVIEW].w && s->AF_NOW
1521     && (s->RIF || s->AE || s->scanning_speed == 0))
1522     {
1523       if ((status = do_focus (s)) != SANE_STATUS_GOOD) return (status);
1524       if (s->val[OPT_AF_ONCE].w) s->AF_NOW = SANE_FALSE;
1525     }
1526 
1527   /* ============= modification for FB620S ============= */
1528   DBG (3, "TEST_UNIT_READY\n");
1529   status = test_unit_ready (s->fd);
1530   if (status != SANE_STATUS_GOOD)
1531     {
1532       DBG (1, "test unit ready failed (%s)\n", sane_strstatus (status));
1533       sanei_scsi_close (s->fd);
1534       s->fd = -1;
1535       return (status);
1536     }
1537 
1538   if (s->hw->info.can_calibrate)
1539     {
1540       DBG (3, "sane_start: sending GET_CALIBRATION_STATUS\n");
1541       buf_size = sizeof (cbuf);
1542       memset (cbuf, 0, buf_size);
1543       status = get_calibration_status (s->fd, cbuf, &buf_size);
1544       if (status != SANE_STATUS_GOOD)
1545 	{
1546 	  DBG (1, "sane_start: GET_CALIBRATION_STATUS failed: %s\n",
1547 	       sane_strstatus (status));
1548 	  sanei_scsi_close (s->fd);
1549 	  s->fd = -1;
1550 	  return (status);
1551 	}
1552 
1553       DBG (1, "cbuf[0] = %d\n", cbuf[0]);
1554       DBG (1, "cbuf[1] = %d\n", cbuf[1]);
1555 
1556       cbuf[0] &= 3;
1557       if (cbuf[0] == 1 || cbuf[0] == 2 || cbuf[0] == 3)
1558 	{
1559 	  status = execute_calibration (s->fd);
1560 	  DBG (3, "sane_start: EXECUTE_CALIBRATION\n");
1561 	  if (status != SANE_STATUS_GOOD)
1562 	    {
1563 	      DBG (1, "sane_start: EXECUTE_CALIBRATION failed\n");
1564 	      sanei_scsi_close (s->fd);
1565 	      s->fd = -1;
1566 	      return (status);
1567 	    }
1568 
1569 	  DBG (3, "after calibration: GET_CALIBRATION_STATUS\n");
1570 	  buf_size = sizeof (cbuf);
1571 	  memset (cbuf, 0, buf_size);
1572 	  status = get_calibration_status (s->fd, cbuf, &buf_size);
1573 	  if (status != SANE_STATUS_GOOD)
1574 	    {
1575 	      DBG (1, "after calibration: GET_CALIBRATION_STATUS failed: %s\n",
1576 		sane_strstatus (status));
1577 	      sanei_scsi_close (s->fd);
1578 	      s->fd = -1;
1579 	      return (status);
1580 	    }
1581 	  DBG (1, "cbuf[0] = %d\n", cbuf[0]);
1582 	  DBG (1, "cbuf[1] = %d\n", cbuf[1]);
1583 	}
1584     }
1585 
1586   status = scan (s->fd);
1587   if (status != SANE_STATUS_GOOD)
1588     {
1589       DBG (1, "start of scan failed: %s\n", sane_strstatus (status));
1590       return (status);
1591     }
1592 
1593   buf_size = sizeof (dbuf);
1594   memset (dbuf, 0, buf_size);
1595   status = get_data_status (s->fd, dbuf, &buf_size);
1596   if (status != SANE_STATUS_GOOD)
1597     {
1598       DBG (1, "GET DATA STATUS failed: %s\n", sane_strstatus (status));
1599       return (status);
1600     }
1601   DBG (5, ">> GET DATA STATUS\n");
1602   DBG (5, "Scan Data Available=%d\n", (dbuf[9] << 16) + (dbuf[10] << 8)
1603        + dbuf[11]);
1604   DBG (5, "Magnified Width=%d\n", (dbuf[12] <<24) + (dbuf[13] << 16)
1605        + (dbuf[14] << 8) + dbuf[15]);
1606   DBG (5, "Magnified Length=%d\n", (dbuf[16] << 24) + (dbuf[17] << 16)
1607        + (dbuf[18] << 8) + dbuf[19]);
1608   DBG (5, "Rest Data=%d bytes\n", (dbuf[20] << 24) + (dbuf[21] << 16)
1609        + (dbuf[22] << 8) + dbuf[23]);
1610   DBG (5, "Filled Data Buffer=%d\n", (dbuf[24] << 24) + (dbuf[25] << 16)
1611        + (dbuf[26] << 8) + dbuf[27]);
1612   DBG (5, "<< GET DATA STATUS\n");
1613 
1614   s->bytes_to_read = s->params.bytes_per_line * s->params.lines;
1615 
1616   if (s->hw->info.model == FB1200)
1617     {
1618       if (s->bytes_to_read != (((size_t) dbuf[9] << 16)
1619       + ((size_t) dbuf[10] << 8) + (size_t) dbuf[11]))
1620 	{
1621 	  s->params.bytes_per_line = (((size_t) dbuf[12] << 24)
1622 	    + ((size_t) dbuf[13] << 16) + ((size_t) dbuf[14] << 8)
1623 	    + (size_t)dbuf[15]);
1624 	  s->params.lines = (((size_t) dbuf[16] << 24)
1625 	    + ((size_t) dbuf[17] << 16) + ((size_t) dbuf[18] << 8)
1626 	    + (size_t) dbuf[19]);
1627 	  s->bytes_to_read = s->params.bytes_per_line * s->params.lines;
1628 
1629 	  mode_str = s->val[OPT_MODE].s;
1630 	  if (!strcmp (mode_str, SANE_VALUE_SCAN_MODE_LINEART))
1631 	    {
1632 	      if (((600 < s->val[OPT_X_RESOLUTION].w)
1633 		|| (600 < s->val[OPT_Y_RESOLUTION].w)))
1634 		{
1635 		  s->params.bytes_per_line *= 2;
1636 		  s->params.lines /= 2;
1637 		}
1638 	      s->params.pixels_per_line = s->params.bytes_per_line * 8;
1639 	    }
1640 	  else if (!strcmp (mode_str, SANE_VALUE_SCAN_MODE_GRAY))
1641 	      s->params.pixels_per_line = s->params.bytes_per_line;
1642 	  else if (!strcmp (mode_str, SANE_VALUE_SCAN_MODE_COLOR)
1643 	    || !strcmp (mode_str, SANE_I18N("Fine color")))
1644 	      s->params.pixels_per_line = s->params.bytes_per_line / 3;
1645 	  else
1646 	    s->params.pixels_per_line = s->params.bytes_per_line / 6;
1647 	}
1648     }
1649 
1650   DBG (1, "%d pixels per line, %d bytes, %d lines high, total %lu bytes, "
1651        "dpi=%d\n", s->params.pixels_per_line, s->params.bytes_per_line,
1652        s->params.lines, (u_long) s->bytes_to_read,
1653        s->val[OPT_X_RESOLUTION].w);
1654 
1655 /**************************************************/
1656 /* modification for FB620S and FB1200S */
1657   s->buf_used = 0;
1658   s->buf_pos = 0;
1659 /**************************************************/
1660 
1661   s->scanning = SANE_TRUE;
1662 
1663   DBG (1, "<< sane_start\n");
1664   return (SANE_STATUS_GOOD);
1665 }
1666 
1667 /**************************************************************************/
1668 
1669 static SANE_Status
sane_read_direct(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)1670 sane_read_direct (SANE_Handle handle, SANE_Byte *buf, SANE_Int max_len,
1671 		  SANE_Int *len)
1672 {
1673   CANON_Scanner *s = handle;
1674   SANE_Status status;
1675   size_t nread;
1676 
1677   DBG (21, ">> sane_read\n");
1678 
1679   *len = 0;
1680   nread = max_len;
1681 
1682   DBG (21, "   sane_read: nread=%d, bytes_to_read=%d\n", (int) nread,
1683   (int) s->bytes_to_read);
1684   if (s->bytes_to_read == 0)
1685     {
1686       do_cancel (s);
1687       return (SANE_STATUS_EOF);
1688     }
1689 
1690   if (!s->scanning) return (do_cancel (s));
1691 
1692   if (nread > s->bytes_to_read) nread = s->bytes_to_read;
1693   status = read_data (s->fd, buf, &nread);
1694   if (status != SANE_STATUS_GOOD)
1695     {
1696       do_cancel (s);
1697       return (SANE_STATUS_IO_ERROR);
1698     }
1699   *len = nread;
1700   s->bytes_to_read -= nread;
1701 
1702   DBG (21, "   sane_read: nread=%d, bytes_to_read=%d\n", (int) nread,
1703   (int) s->bytes_to_read);
1704   DBG (21, "<< sane_read\n");
1705   return (SANE_STATUS_GOOD);
1706 }
1707 
1708 /**************************************************************************/
1709 
1710 static SANE_Status
read_fs2710(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)1711 read_fs2710 (SANE_Handle handle, SANE_Byte *buf, SANE_Int max_len,
1712 	     SANE_Int *len)
1713 {
1714   CANON_Scanner *s = handle;
1715   SANE_Status status;
1716   int c;
1717   size_t i, nread, nread2;
1718   u_char *p;
1719 #if defined(WORDS_BIGENDIAN)
1720   u_char b;
1721 #endif
1722 
1723   DBG (21, ">> sane_read\n");
1724 
1725   *len = 0;
1726   nread = max_len;
1727 
1728   DBG (21, "   sane_read: nread=%d, bytes_to_read=%d\n", (int) nread,
1729   (int) s->bytes_to_read);
1730 
1731   if (nread > s->bytes_to_read) nread = s->bytes_to_read;
1732   if (s->bytes_to_read == 0)
1733     {
1734       do_cancel (s);
1735       return (SANE_STATUS_EOF);
1736     }
1737 
1738   if (!s->scanning) return (do_cancel (s));
1739 
1740   /* We must receive 2 little-endian bytes per pixel and colour.
1741      In raw mode we must swap the bytes if we are running a big-endian
1742      architecture (SANE standard 3.2.1), and pass them both.
1743      Otherwise the other subroutines expect only 1 byte, so we must
1744      set up an intermediate buffer which is twice as large
1745      as buf, and then map this buffer to buf. */
1746 
1747   if (!strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR))
1748     {
1749       if (max_len > s->auxbuf_len)
1750 	{				/* extend buffer? */
1751 	  if (s->auxbuf_len > 0) free (s->auxbuf);
1752 	  s->auxbuf_len = max_len;
1753 	  if ((s->auxbuf = (u_char *) malloc (2 * max_len)) == NULL)
1754 	    {
1755 	      DBG (1, "sane_read buffer size insufficient\n");
1756 	      do_cancel (s);
1757 	      return SANE_STATUS_NO_MEM;
1758 	    }
1759 	}
1760 
1761       nread2 = 2 * nread;
1762       if ((status = read_data (s->fd, s->auxbuf, &nread2)) != SANE_STATUS_GOOD)
1763 	{
1764 	  do_cancel (s);
1765 	  return (SANE_STATUS_IO_ERROR);
1766 	}
1767       nread = nread2 / 2;
1768       for (i = 0, p = s->auxbuf; i < nread; i++)
1769 	{
1770 	  c = *p++ >> 4;
1771 	  c |= *p++ << 4;
1772 	  *buf++ = s->gamma_map[s->colour++][c];
1773 	  if (s->colour > 3) s->colour = 1;	/* cycle through RGB */
1774 	}
1775     }
1776   else
1777     {
1778       if ((status = read_data (s->fd, buf, &nread)) != SANE_STATUS_GOOD)
1779 	{
1780 	  do_cancel (s);
1781 	  return (SANE_STATUS_IO_ERROR);
1782 	}
1783 #if defined(WORDS_BIGENDIAN)
1784       for (p = buf; p < buf + nread; p++)
1785 	{
1786 	  b = *p;
1787 	  *p = *(p + 1);
1788 	  p++;
1789 	  *p = b;
1790 	}
1791 #endif
1792     }
1793   *len = nread;
1794   s->bytes_to_read -= nread;
1795 
1796   DBG (21, "   sane_read: nread=%d, bytes_to_read=%d\n", (int) nread,
1797   (int) s->bytes_to_read);
1798   DBG (21, "<< sane_read\n");
1799   return (SANE_STATUS_GOOD);
1800 }
1801 
1802 /**************************************************************************/
1803 /* modification for FB620S */
1804 
1805 static SANE_Status
read_fb620(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)1806 read_fb620 (SANE_Handle handle, SANE_Byte *buf, SANE_Int max_len,
1807 	    SANE_Int *len)
1808 {
1809   CANON_Scanner *s = handle;
1810   SANE_Status status;
1811   SANE_Byte *out, *red, *green, *blue;
1812   SANE_Int ncopy;
1813   size_t nread = 0, i, pixel_per_line;
1814 
1815   DBG (21, ">> read_fb620\n");
1816 
1817   *len = 0;
1818 
1819   DBG (21, "   read_fb620: nread=%d, bytes_to_read=%d\n", (int) nread,
1820   (int) s->bytes_to_read);
1821 
1822   if (s->bytes_to_read == 0 && s->buf_pos == s->buf_used)
1823     {
1824       s->reset_flag = 0;	/* no reset */
1825 
1826       do_cancel (s);
1827       DBG (21, "do_cancel(EOF)\n");
1828       DBG (21, "reset_flag = %d\n", s->reset_flag);
1829       return (SANE_STATUS_EOF);
1830     }
1831   else
1832     {
1833       s->reset_flag = 1;	/* do reset */
1834       DBG (21, "reset_flag = %d\n", s->reset_flag);
1835     }
1836   DBG (21, "   read_fb620: buf_pos=%d, buf_used=%d\n", s->buf_pos,
1837        s->buf_used);
1838 
1839   if (!s->scanning)
1840     return (do_cancel (s));
1841 
1842   if (s->buf_pos < s->buf_used)
1843     {
1844       ncopy = s->buf_used - s->buf_pos;
1845       if (ncopy > max_len)
1846 	ncopy = max_len;
1847       memcpy (buf, &(s->outbuffer[s->buf_pos]), ncopy);
1848 
1849       max_len -= ncopy;
1850       *len += ncopy;
1851       buf = &(buf[ncopy]);
1852       s->buf_pos += ncopy;
1853     }
1854 
1855   if (s->buf_pos >= s->buf_used && s->bytes_to_read)
1856     {
1857       /* buffer is empty: read in scan line and sort color data as shown
1858          above */
1859 
1860       nread = s->params.bytes_per_line;
1861 
1862       if (nread > s->bytes_to_read)
1863 	nread = s->bytes_to_read;
1864 
1865       status = read_data (s->fd, s->inbuffer, &nread);
1866 
1867       if (status != SANE_STATUS_GOOD)
1868 	{
1869 	  do_cancel (s);
1870 	  return (SANE_STATUS_IO_ERROR);
1871 	}
1872 
1873       s->buf_used = s->params.bytes_per_line;
1874 
1875       out = s->outbuffer;
1876       pixel_per_line = s->params.pixels_per_line;
1877 
1878       red = s->inbuffer;
1879       green = &(s->inbuffer[pixel_per_line]);
1880       blue = &(s->inbuffer[2 * pixel_per_line]);
1881 
1882       for (i = 0; i < pixel_per_line; i++)
1883 	{
1884 	  *out++ = *red++;
1885 	  *out++ = *green++;
1886 	  *out++ = *blue++;
1887 	}
1888 
1889       s->buf_pos = 0;
1890 
1891       s->bytes_to_read -= s->buf_used;
1892 
1893     }
1894 
1895   if (max_len && s->buf_pos < s->buf_used)
1896     {
1897       ncopy = s->buf_used - s->buf_pos;
1898       if (ncopy > max_len)
1899 	ncopy = max_len;
1900       memcpy (buf, &(s->outbuffer[s->buf_pos]), ncopy);
1901       *len += ncopy;
1902       s->buf_pos += ncopy;
1903     }
1904 
1905   DBG (21, "<< read_fb620\n");
1906   return (SANE_STATUS_GOOD);
1907 }
1908 
1909 /**************************************************************************/
1910 /* modification for FB1200S */
1911 
1912 static SANE_Status
read_fb1200(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)1913 read_fb1200 (SANE_Handle handle, SANE_Byte *buf, SANE_Int max_len,
1914 SANE_Int *len)
1915 {
1916   CANON_Scanner *s = handle;
1917   SANE_Status status;
1918   SANE_Byte *firstimage, *secondimage/*, inmask, outmask, outbyte,
1919 	    primaryHigh[256], primaryLow[256], secondaryHigh[256],
1920 	    secondaryLow[256] */;
1921   SANE_Int ncopy;
1922   u_char dbuf[28];
1923   size_t buf_size, nread, remain, nwritten, nremain, pos, pix, pixel_per_line,
1924 	 byte, byte_per_line/*, bit*/;
1925   ssize_t wres, readres;
1926   int maxpix;
1927 
1928   DBG (21, ">> read_fb1200\n");
1929 
1930   buf_size = sizeof (dbuf);
1931   memset (dbuf, 0, buf_size);
1932   status = get_data_status (s->fd, dbuf, &buf_size);
1933   if (status != SANE_STATUS_GOOD)
1934     {
1935       DBG (1, "GET DATA STATUS failed: %s\n", sane_strstatus (status));
1936       return (status);
1937     }
1938   DBG (5, ">> GET DATA STATUS\n");
1939   DBG (5, "Scan Data Available=%d\n", (dbuf[9] << 16) + (dbuf[10] << 8)
1940     + dbuf[11]);
1941   DBG (5, "Rest Data=%d bytes\n", (dbuf[20] << 24) + (dbuf[21] << 16)
1942     + (dbuf[22] << 8) + dbuf[23]);
1943   DBG (5, "Filled Data Buffer=%d\n", (dbuf[24] << 24) + (dbuf[25] << 16)
1944     + (dbuf[26] << 8) + dbuf[27]);
1945   DBG (5, "temp file position:%u\n", (unsigned int) lseek(s->tmpfile,
1946   0, SEEK_CUR));
1947   DBG (5, "<< GET DATA STATUS\n");
1948 
1949   *len = 0;
1950 
1951   DBG (21, "   read_fb1200: bytes_to_read=%d\n",
1952   (int) s->bytes_to_read);
1953 
1954   if (s->bytes_to_read == 0 && s->buf_pos == s->buf_used)
1955     {
1956       do_cancel (s);
1957       DBG (21, "do_cancel(EOF)\n");
1958       return (SANE_STATUS_EOF);
1959     }
1960 
1961   DBG (21, "   read_fb1200: buf_pos=%d, buf_used=%d\n", s->buf_pos,
1962        s->buf_used);
1963 
1964   if (!s->scanning)
1965     return (do_cancel (s));
1966 
1967   if (s->buf_pos >= s->buf_used && s->bytes_to_read)
1968     {
1969       nread = s->params.bytes_per_line / 2;
1970 
1971       if (nread > s->bytes_to_read)
1972 	nread = s->bytes_to_read;
1973 
1974       status = read_data (s->fd, s->inbuffer, &nread);
1975 
1976       if (status != SANE_STATUS_GOOD)
1977 	{
1978 	  do_cancel (s);
1979 	  return (SANE_STATUS_IO_ERROR);
1980 	}
1981 
1982       /**** save the primary scan data to tmpfile ****/
1983 
1984       if ((SANE_Int) s->bytes_to_read > s->params.bytes_per_line
1985 	* s->params.lines / 2)
1986 	{
1987 	  remain = nread;
1988 	  nwritten = 0;
1989 	  while (remain)
1990 	    {
1991 	      errno = 0;
1992 	      wres = write (s->tmpfile, &s->inbuffer[nwritten], remain);
1993 	      if (wres == -1)
1994 		{
1995 		  DBG(1, "error write tmp file: %i, %s\n", errno,
1996 		    strerror(errno));
1997 		  do_cancel(s);
1998 		  return (SANE_STATUS_NO_MEM);
1999 		}
2000 	      remain -= wres;
2001 	      nwritten += wres;
2002 	    }
2003 
2004 	  s->bytes_to_read -= nread;
2005 
2006 	  if ((SANE_Int) s->bytes_to_read <= s->params.bytes_per_line
2007 	    * s->params.lines / 2)
2008 	    {
2009 	      if ((SANE_Int) s->bytes_to_read < s->params.bytes_per_line
2010 		* s->params.lines / 2)
2011 		DBG(1, "warning: read more data for the primary scan "
2012 		  "than expected\n");
2013 
2014 	      lseek (s->tmpfile, 0L, SEEK_SET);
2015 	      *len = 0;
2016 	      *buf = 0;
2017 	      return (SANE_STATUS_GOOD);
2018 	    }
2019 
2020 	  DBG(1, "writing: the primary data to tmp file\n");
2021 	  *len = 0;
2022 	  *buf = 0;
2023 	  return (SANE_STATUS_GOOD);
2024 	}
2025       /** the primary scan data from tmpfile and the secondary scan data
2026 	  are merged **/
2027 
2028       s->buf_used = s->params.bytes_per_line;
2029       byte_per_line = s->params.bytes_per_line;
2030       pixel_per_line = s->params.pixels_per_line;
2031 
2032 
2033       /** read an entire scan line from the primary scan **/
2034 
2035       remain = nread;
2036       pos = 0;
2037       firstimage = &(s->inbuffer[byte_per_line/2]);
2038 
2039       while (remain > 0)
2040 	{
2041 	  nremain = (remain < SSIZE_MAX)? remain: SSIZE_MAX;
2042 	  errno = 0;
2043 	  readres = read (s->tmpfile, &(firstimage[pos]), nremain);
2044 	  if (readres == -1)
2045 	    {
2046 	      DBG(1, "error reading tmp file: %i %s\n", errno,
2047 		strerror(errno));
2048 	      do_cancel(s);
2049 	      return (SANE_STATUS_IO_ERROR);
2050 	    }
2051 	  if (readres == 0)
2052 	    {
2053 	      DBG(1, "0 byte read from temp file. premature EOF?\n");
2054 	      return (SANE_STATUS_INVAL);
2055 	      /* perhaps an error return? */
2056 	    }
2057 	  DBG(1, "reading: the primary data from tmp file\n");
2058 	  remain -= readres;
2059 	  pos += readres;
2060 	}
2061 
2062       secondimage = s->inbuffer;
2063 
2064       if (!strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR))
2065 	{
2066 	  maxpix = pixel_per_line / 2;
2067 	  for (pix = 0; (int) pix < maxpix; pix++)
2068 	    {
2069 	      s->outbuffer[6 * pix] = secondimage[3 * pix];
2070 	      s->outbuffer[6 * pix + 1] = secondimage[3 * pix + 1];
2071 	      s->outbuffer[6 * pix + 2] = secondimage[3 * pix + 2];
2072 	      s->outbuffer[6 * pix + 3] = firstimage[3 * pix];
2073 	      s->outbuffer[6 * pix + 4] = firstimage[3 * pix + 1];
2074 	      s->outbuffer[6 * pix + 5] = firstimage[3 * pix + 2];
2075 	    }
2076 	}
2077       else if (!strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY))
2078 	{
2079 	  for (pix = 0; pix < pixel_per_line / 2; pix++)
2080 	    {
2081 	      s->outbuffer[2 * pix] = secondimage[pix];
2082 	      s->outbuffer[2 * pix + 1] = firstimage[pix];
2083 	    }
2084 	}
2085       else /* for lineart mode */
2086 	{
2087 	  maxpix = byte_per_line / 2;
2088 	  for (byte = 0; (int) byte < maxpix; byte++)
2089 	    {
2090 	      s->outbuffer[2 * byte] = primaryHigh[firstimage[byte]]
2091 		| secondaryHigh[secondimage[byte]];
2092 	      s->outbuffer[2 * byte + 1] = primaryLow[firstimage[byte]]
2093 		| secondaryLow[secondimage[byte]];
2094 #if 0
2095 	      inmask = 128;
2096 	      outmask = 128;
2097 	      outbyte = 0;
2098 	      for (bit = 0; bit < 4; bit++)
2099 		{
2100 		  if (inmask == (secondimage[byte] & inmask))
2101 		    outbyte = outbyte | outmask;
2102 		  outmask = outmask >> 1;
2103 		  if (inmask == (firstimage[byte] & inmask))
2104 		    outbyte = outbyte | outmask;
2105 		  outmask = outmask >> 1;
2106 		  inmask = inmask >> 1;
2107 		}
2108 	      s->outbuffer[2 * byte] = outbyte;
2109 
2110 	      outmask = 128;
2111 	      outbyte = 0;
2112 	      for (bit = 0; bit < 4; bit++)
2113 		{
2114 		  if (inmask == (secondimage[byte] & inmask))
2115 		    outbyte = outbyte | outmask;
2116 		  outmask = outmask >> 1;
2117 		  if (inmask == (firstimage[byte] & inmask))
2118 		    outbyte = outbyte | outmask;
2119 		  outmask = outmask >> 1;
2120 		  inmask = inmask >> 1;
2121 		}
2122 	      s->outbuffer[2 * byte + 1] = outbyte;
2123 #endif
2124 	    }
2125 	}
2126 
2127       s->buf_pos = 0;
2128       s->bytes_to_read -= nread;
2129     }
2130 
2131   if (max_len && s->buf_pos < s->buf_used)
2132     {
2133       ncopy = s->buf_used - s->buf_pos;
2134       if (ncopy > max_len)
2135 	ncopy = max_len;
2136       memcpy (buf, &(s->outbuffer[s->buf_pos]), ncopy * 2);
2137       *len += ncopy;
2138       s->buf_pos += ncopy;
2139     }
2140 
2141   DBG (21, "<< read_fb1200\n");
2142   return (SANE_STATUS_GOOD);
2143 }
2144 
2145 /**************************************************************************/
2146 SANE_Status
sane_read(SANE_Handle handle,SANE_Byte * buf,SANE_Int max_len,SANE_Int * len)2147 sane_read (SANE_Handle handle, SANE_Byte *buf, SANE_Int max_len,
2148 	   SANE_Int *len)
2149 {
2150   CANON_Scanner *s = handle;
2151   SANE_Status status;
2152   if (s->hw->info.model == FB620 && s->params.format == SANE_FRAME_RGB)
2153     status = read_fb620 (handle, buf, max_len, len);
2154   else if (s->hw->info.model == FS2710)
2155     status = read_fs2710 (handle, buf, max_len, len);
2156   else if (s->hw->info.model == FB1200 && ((600 < s->val[OPT_X_RESOLUTION].w)
2157     || (600 < s->val[OPT_Y_RESOLUTION].w)))
2158     status = read_fb1200 (handle, buf, max_len, len);
2159   else
2160     status = sane_read_direct (handle, buf, max_len, len);
2161   if (s->time0 == -1)
2162     s->time0 = 0;
2163   else
2164     time (&(s->time0));
2165 
2166   DBG (11, "sane_read: time0 = %ld\n", s->time0);
2167   s->switch_preview = s->val[OPT_PREVIEW].w;
2168   return (status);
2169 }
2170 
2171 /**************************************************************************/
2172 
2173 void
sane_cancel(SANE_Handle handle)2174 sane_cancel (SANE_Handle handle)
2175 {
2176   CANON_Scanner *s = handle;
2177   DBG (1, ">> sane_cancel\n");
2178 
2179 /******** for FB1200S ************/
2180   if(s->hw->info.model == FB1200)
2181    {
2182     if (s->tmpfile != -1)
2183      {
2184       close (s->tmpfile);
2185       DBG(1, " ****** tmpfile is closed ****** \n");
2186      }
2187     else
2188      {
2189       DBG(1, "tmpfile is failed\n");
2190 /*    return (SANE_STATUS_INVAL);*/
2191      }
2192    }
2193 /*********************************/
2194 
2195   s->scanning = SANE_FALSE;
2196   DBG (1, "<< sane_cancel\n");
2197 }
2198 
2199 /**************************************************************************/
2200 
2201 SANE_Status
sane_set_io_mode(SANE_Handle __sane_unused__ handle,SANE_Bool __sane_unused__ non_blocking)2202 sane_set_io_mode (SANE_Handle __sane_unused__ handle,
2203 SANE_Bool __sane_unused__ non_blocking)
2204 {
2205   DBG (1, ">> sane_set_io_mode\n");
2206   DBG (1, "<< sane_set_io_mode\n");
2207   return SANE_STATUS_UNSUPPORTED;
2208 }
2209 
2210 /**************************************************************************/
2211 
2212 SANE_Status
sane_get_select_fd(SANE_Handle __sane_unused__ handle,SANE_Int __sane_unused__ * fd)2213 sane_get_select_fd (SANE_Handle __sane_unused__ handle,
2214 SANE_Int __sane_unused__ * fd)
2215 {
2216   DBG (1, ">> sane_get_select_fd\n");
2217   DBG (1, "<< sane_get_select_fd\n");
2218 
2219   return SANE_STATUS_UNSUPPORTED;
2220 }
2221 
2222 /**************************************************************************/
2223