xref: /third_party/backends/backend/canon-sane.c (revision 141cc406)
1SANE_Status
2sane_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, SANE_CURRENT_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
89void
90sane_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
108SANE_Status
109sane_get_devices (const SANE_Device *** device_list,
110SANE_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
136SANE_Status
137sane_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
238void
239sane_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
278const SANE_Option_Descriptor *
279sane_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/**************************************************************************/
295SANE_Status
296sane_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
1022SANE_Status
1023sane_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
1104SANE_Status
1105sane_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  DBG (1, ">> sane_start\n");
1115
1116  s->tmpfile = -1; /* for FB1200S */
1117
1118/******* making a tempfile for 1200 dpi scanning of FB1200S ******/
1119  if (s->hw->info.model == FB1200)
1120    {
1121      char tmpfilename[] = "/tmp/canon.XXXXXX"; /* for FB1200S */
1122
1123      s->tmpfile = mkstemp(tmpfilename);
1124      if (s->tmpfile == -1)
1125	{
1126	  DBG(1, "error opening temp file %s\n", tmpfilename);
1127	  DBG(1, "errno: %i; %s\n", errno, strerror(errno));
1128	  errno = 0;
1129	  return (SANE_STATUS_INVAL);
1130	}
1131      DBG(1, " ****** tmpfile is opened ****** \n");
1132      unlink(tmpfilename);
1133    }
1134/******************************************************************/
1135
1136  s->scanning = SANE_FALSE;
1137
1138  if ((s->hw->adf.Status != ADF_STAT_NONE)
1139      && (s->val[OPT_FLATBED_ONLY].w != SANE_TRUE)
1140      && (s->hw->adf.Problem != 0))
1141    {
1142      DBG (3, "SCANNER ADF HAS A PROBLEM\n");
1143      if (s->hw->adf.Problem & 0x08)
1144	{
1145	  status = SANE_STATUS_COVER_OPEN;
1146	  DBG (3, "ADF Cover Open\n");
1147	}
1148      else if (s->hw->adf.Problem & 0x04)
1149	{
1150	  status = SANE_STATUS_JAMMED;
1151	  DBG (3, "ADF Paper Jam\n");
1152	}
1153      else			/* adf.Problem = 0x02 */
1154	{
1155	  status = SANE_STATUS_NO_DOCS;
1156	  DBG (3, "ADF No More Documents\n");
1157	}
1158      return status;
1159    }
1160  else if ((s->hw->adf.Status != ADF_STAT_NONE)
1161	   && (s->val[OPT_FLATBED_ONLY].w == SANE_TRUE))
1162    {
1163      set_adf_mode (s->fd, s->hw->adf.Priority);
1164      /* 2.23 define ADF Mode */
1165    }
1166
1167  /* First make sure we have a current parameter set.  Some of the
1168     parameters will be overwritten below, but that's OK.  */
1169  status = sane_get_parameters (s, 0);
1170  if (status != SANE_STATUS_GOOD)
1171    return status;
1172
1173  status = sanei_scsi_open (s->hw->sane.name, &s->fd, sense_handler, s->hw);
1174  if (status != SANE_STATUS_GOOD)
1175    {
1176      DBG (1, "open of %s failed: %s\n", s->hw->sane.name,
1177	sane_strstatus (status));
1178      return (status);
1179    }
1180
1181#if 0				/* code moved after define_scan() calls */
1182  /* Do focus, but not for the preview */
1183  if (SANE_OPTION_IS_ACTIVE(s->opt[OPT_FOCUS_GROUP].cap)
1184    && !s->val[OPT_PREVIEW].w && s->AF_NOW)
1185    {
1186      if ((status = do_focus (s)) != SANE_STATUS_GOOD) return (status);
1187      if (s->val[OPT_AF_ONCE].w) s->AF_NOW = SANE_FALSE;
1188    }
1189#endif
1190
1191  if (s->val[OPT_CUSTOM_GAMMA].w)
1192    {
1193      if ((status = do_gamma (s)) != SANE_STATUS_GOOD) return (status);
1194    }
1195
1196  DBG (3, "attach: sending GET SCAN MODE for scan control conditions\n");
1197  memset (ebuf, 0, sizeof (ebuf));
1198  buf_size = 20;
1199  status = get_scan_mode (s->fd, (u_char) SCAN_CONTROL_CONDITIONS,
1200    ebuf, &buf_size);
1201  if (status != SANE_STATUS_GOOD)
1202    {
1203      DBG (1, "attach: GET SCAN MODE for scan control conditions failed\n");
1204      sanei_scsi_close (s->fd);
1205      return (SANE_STATUS_INVAL);
1206    }
1207  for (i = 0; i < buf_size; i++)
1208    DBG (3, "scan mode control byte[%d] = %d\n", (int) i, ebuf[i]);
1209
1210  if (s->hw->adf.Status != ADF_STAT_NONE)
1211    {
1212      DBG (3, "attach: sending GET SCAN MODE for transparency unit\n");
1213      memset (ebuf, 0, sizeof (ebuf));
1214      buf_size = 12;
1215      status = get_scan_mode (s->fd, (u_char) TRANSPARENCY_UNIT,
1216			      ebuf, &buf_size);
1217      if (status != SANE_STATUS_GOOD)
1218	{
1219	  DBG (1, "attach: GET SCAN MODE for transparency unit failed\n");
1220	  sanei_scsi_close (s->fd);
1221	  return (SANE_STATUS_INVAL);
1222	}
1223      for (i = 0; i < buf_size; i++)
1224	DBG (3, "scan mode control byte[%d] = %d\n", (int) i,
1225	ebuf[i]);
1226    }
1227
1228  mode_str = s->val[OPT_MODE].s;
1229  s->xres = s->val[OPT_X_RESOLUTION].w;
1230  s->yres = s->val[OPT_Y_RESOLUTION].w;
1231
1232  if (s->val[OPT_RESOLUTION_BIND].w || s->val[OPT_PREVIEW].w)
1233      s->yres = s->xres;
1234
1235  s->ulx = SANE_UNFIX (s->val[OPT_TL_X].w) * s->hw->info.mud / MM_PER_INCH;
1236  s->uly = SANE_UNFIX (s->val[OPT_TL_Y].w) * s->hw->info.mud / MM_PER_INCH;
1237
1238  s->width = SANE_UNFIX (s->val[OPT_BR_X].w - s->val[OPT_TL_X].w)
1239    * s->hw->info.mud / MM_PER_INCH;
1240  s->length = SANE_UNFIX (s->val[OPT_BR_Y].w - s->val[OPT_TL_Y].w)
1241    * s->hw->info.mud / MM_PER_INCH;
1242
1243  DBG (11, "s->width='%d', s->length='%d'\n", s->width, s->length);
1244
1245  if (s->hw->info.model != CS2700 && s->hw->info.model != FS2710)
1246    {
1247      if (!strcmp (mode_str, SANE_VALUE_SCAN_MODE_LINEART)
1248      || !strcmp (mode_str, SANE_VALUE_SCAN_MODE_HALFTONE))
1249	s->RIF = s->val[OPT_HNEGATIVE].w;
1250      else
1251	s->RIF = !s->val[OPT_HNEGATIVE].w;
1252    }
1253
1254  s->brightness = s->val[OPT_BRIGHTNESS].w;
1255  s->contrast = s->val[OPT_CONTRAST].w;
1256  s->threshold = s->val[OPT_THRESHOLD].w;
1257  s->bpp = s->params.depth;
1258
1259  s->GRC = s->val[OPT_CUSTOM_GAMMA].w;
1260  s->Mirror = s->val[OPT_MIRROR].w;
1261  s->AE = s->val[OPT_AE].w;
1262
1263  s->HiliteG = s->val[OPT_HILITE_G].w;
1264  s->ShadowG = s->val[OPT_SHADOW_G].w;
1265  if (s->val[OPT_BIND_HILO].w)
1266    {
1267      s->HiliteR = s->val[OPT_HILITE_G].w;
1268      s->ShadowR = s->val[OPT_SHADOW_G].w;
1269      s->HiliteB = s->val[OPT_HILITE_G].w;
1270      s->ShadowB = s->val[OPT_SHADOW_G].w;
1271    }
1272  else
1273    {
1274      s->HiliteR = s->val[OPT_HILITE_R].w;
1275      s->ShadowR = s->val[OPT_SHADOW_R].w;
1276      s->HiliteB = s->val[OPT_HILITE_B].w;
1277      s->ShadowB = s->val[OPT_SHADOW_B].w;
1278    }
1279
1280  if (!strcmp (mode_str, SANE_VALUE_SCAN_MODE_LINEART))
1281    {
1282      s->image_composition = 0;
1283    }
1284  else if (!strcmp (mode_str, SANE_VALUE_SCAN_MODE_HALFTONE))
1285    {
1286      s->image_composition = 1;
1287    }
1288  else if (!strcmp (mode_str, SANE_VALUE_SCAN_MODE_GRAY))
1289    {
1290      s->image_composition = 2;
1291    }
1292  else if (!strcmp (mode_str, SANE_VALUE_SCAN_MODE_COLOR)
1293  || !strcmp (mode_str, SANE_I18N("Fine color")))
1294    {
1295      s->image_composition = 5;
1296    }
1297  else if (!strcmp (mode_str, SANE_I18N("Raw")))
1298    {
1299      s->image_composition = 5;
1300    }
1301  else
1302    {
1303      s->image_composition = 5;
1304    }
1305
1306  memset (wbuf, 0, sizeof (wbuf));
1307  wbuf[7] = 64;
1308  wbuf[10] = s->xres >> 8;
1309  wbuf[11] = s->xres;
1310  wbuf[12] = s->yres >> 8;
1311  wbuf[13] = s->yres;
1312  wbuf[14] = s->ulx >> 24;
1313  wbuf[15] = s->ulx >> 16;
1314  wbuf[16] = s->ulx >> 8;
1315  wbuf[17] = s->ulx;
1316  wbuf[18] = s->uly >> 24;
1317  wbuf[19] = s->uly >> 16;
1318  wbuf[20] = s->uly >> 8;
1319  wbuf[21] = s->uly;
1320  wbuf[22] = s->width >> 24;
1321  wbuf[23] = s->width >> 16;
1322  wbuf[24] = s->width >> 8;
1323  wbuf[25] = s->width;
1324  wbuf[26] = s->length >> 24;
1325  wbuf[27] = s->length >> 16;
1326  wbuf[28] = s->length >> 8;
1327  wbuf[29] = s->length;
1328  wbuf[30] = s->brightness;
1329  wbuf[31] = s->threshold;
1330  wbuf[32] = s->contrast;
1331  wbuf[33] = s->image_composition;
1332  wbuf[34] = (s->hw->info.model == FS2710) ? 12 : s->bpp;
1333  wbuf[36] = 1;
1334  wbuf[37] = (1 << 7) + 0x03;
1335  wbuf[50] = (s->GRC << 3) | (s->Mirror << 2);
1336#if 1
1337   wbuf[50] |= s->AE;	/* AE also for preview; needed by frontend controls */
1338#else
1339  if (!s->val[OPT_PREVIEW].w) wbuf[50] |= s->AE; /* AE not during preview */
1340#endif
1341  wbuf[54] = 2;
1342  wbuf[57] = 1;
1343  wbuf[58] = 1;
1344  wbuf[59] = s->HiliteR;
1345  wbuf[60] = s->ShadowR;
1346  wbuf[62] = s->HiliteG;
1347  wbuf[64] = s->ShadowG;
1348  wbuf[70] = s->HiliteB;
1349  wbuf[71] = s->ShadowB;
1350
1351  DBG (7, "RIF=%d, GRC=%d, Mirror=%d, AE=%d, Speed=%d\n", s->RIF, s->GRC,
1352    s->Mirror, s->AE, s->scanning_speed);
1353  DBG (7, "HR=%d, SR=%d, HG=%d, SG=%d, HB=%d, SB=%d\n", s->HiliteR,
1354    s->ShadowR, s->HiliteG, s->ShadowG, s->HiliteB, s->ShadowB);
1355
1356  if (s->hw->info.model == FB620)	/* modification for FB620S */
1357    {
1358      wbuf[36] = 0;
1359      wbuf[37] = (s->RIF << 7) + 0x3;
1360      wbuf[50] = s->GRC << 3;
1361      wbuf[54] = 0;
1362      wbuf[57] = 0;
1363      wbuf[58] = 0;
1364    }
1365  else if (s->hw->info.model == FB1200)	/* modification for FB1200S */
1366    {
1367#if 0
1368      wbuf[34] = (((600 < s->val[OPT_X_RESOLUTION].w)
1369	|| (600 < s->val[OPT_Y_RESOLUTION].w))
1370	&& (strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_LINEART) != 0))
1371	? 12 : s->bpp;
1372#endif
1373      wbuf[36] = 0;
1374      wbuf[37] = (s->RIF << 7) + 0x3;
1375      wbuf[50] = (1 << 4) | (s->GRC << 3);
1376      wbuf[57] = 1;
1377      wbuf[58] = 1;
1378    }
1379  else if (s->hw->info.model == IX4015) /* modification for IX-4015 */
1380    {
1381      wbuf[36] = 0;
1382      wbuf[37] = (s->RIF << 7);
1383      wbuf[57] = 0;
1384      wbuf[58] = 0;
1385      /* no highlight and shadow control */
1386      wbuf[59] = 0;
1387      wbuf[60] = 0;
1388      wbuf[62] = 0;
1389      wbuf[64] = 0;
1390      wbuf[70] = 0;
1391      wbuf[71] = 0;
1392    }
1393
1394  buf_size = sizeof (wbuf);
1395  status = set_window (s->fd, wbuf);
1396  if (status != SANE_STATUS_GOOD)
1397    {
1398      DBG (1, "SET WINDOW failed: %s\n", sane_strstatus (status));
1399      return (status);
1400    }
1401  if (s->hw->info.model == FS2710)
1402    status = set_parameters_fs2710 (s);
1403  buf_size = sizeof (wbuf);
1404  memset (wbuf, 0, buf_size);
1405  status = get_window (s->fd, wbuf, &buf_size);
1406  if (status != SANE_STATUS_GOOD)
1407    {
1408      DBG (1, "GET WINDOW failed: %s\n", sane_strstatus (status));
1409      return (status);
1410    }
1411  DBG (5, "xres=%d\n", (wbuf[10] << 8) + wbuf[11]);
1412  DBG (5, "yres=%d\n", (wbuf[12] << 8) + wbuf[13]);
1413  DBG (5, "ulx=%d\n", (wbuf[14] << 24) + (wbuf[15] << 16) + (wbuf[16] << 8)
1414    + wbuf[17]);
1415  DBG (5, "uly=%d\n", (wbuf[18] << 24) + (wbuf[19] << 16) + (wbuf[20] << 8)
1416    + wbuf[21]);
1417  DBG (5, "width=%d\n", (wbuf[22] << 24) + (wbuf[23] << 16) + (wbuf[24] << 8)
1418    + wbuf[25]);
1419  DBG (5, "length=%d\n", (wbuf[26] << 24) + (wbuf[27] << 16) + (wbuf[28] << 8)
1420    + wbuf[29]);
1421  DBG (5, "Highlight Red=%d\n", wbuf[59]);
1422  DBG (5, "Shadow Red=%d\n", wbuf[60]);
1423  DBG (5, "Highlight (Green)=%d\n", wbuf[62]);
1424  DBG (5, "Shadow (Green)=%d\n", wbuf[64]);
1425  DBG (5, "Highlight Blue=%d\n", wbuf[70]);
1426  DBG (5, "Shadow Blue=%d\n", wbuf[71]);
1427
1428  if (s->hw->tpu.Status == TPU_STAT_ACTIVE || s->hw->info.is_filmscanner)
1429    {
1430      DBG (3, "sane_start: sending DEFINE SCAN MODE for transparency unit, "
1431	"NP=%d, Negative film type=%d\n", !s->RIF, s->negative_filmtype);
1432      memset (wbuf, 0, sizeof (wbuf));
1433      wbuf[0] = 0x02;
1434      wbuf[1] = 6;
1435      wbuf[2] = 0x80;
1436      wbuf[3] = 0x05;
1437      wbuf[4] = 39;
1438      wbuf[5] = 16;
1439      wbuf[6] = !s->RIF;
1440      wbuf[7] = s->negative_filmtype;
1441      status = define_scan_mode (s->fd, TRANSPARENCY_UNIT, wbuf);
1442      /* note: If we implement a TPU for the FB1200S, we need
1443         TRANSPARENCY_UNIT_FB1200 here. */
1444      if (status != SANE_STATUS_GOOD)
1445	{
1446	  DBG (1, "define scan mode failed: %s\n", sane_strstatus (status));
1447	  return (status);
1448	}
1449    }
1450
1451  DBG (3, "sane_start: sending DEFINE SCAN MODE for scan control "
1452    "conditions\n");
1453  memset (wbuf, 0, sizeof (wbuf));
1454  wbuf[0] = 0x20;
1455  if (s->hw->info.model == FB1200)
1456    {
1457      wbuf[1] = 17;
1458      wbuf[16] = 3;
1459      wbuf[17] = 8;
1460      wbuf[18] = (1 << 7) | (1 << 3);
1461
1462      DBG (3, "sane_start: sending DEFINE SCAN MODE for scan control "
1463	"conditions of FB1200\n");
1464      status = define_scan_mode (s->fd, SCAN_CONTROL_CON_FB1200, wbuf);
1465    }
1466  else
1467    {
1468      wbuf[1] = 14;
1469      /* For preview use always normal speed: */
1470      if (!s->val[OPT_PREVIEW].w && s->hw->info.is_filmscanner)
1471	wbuf[11] = s->scanning_speed;
1472      wbuf[15] = (s->hw->info.model == FB620
1473	&& !strcmp (mode_str, SANE_I18N("Fine color"))
1474	&& !s->val[OPT_PREVIEW].w) ? 1 << 3 : 0;
1475      status = define_scan_mode (s->fd, SCAN_CONTROL_CONDITIONS, wbuf);
1476    }
1477  if (status != SANE_STATUS_GOOD)
1478    {
1479      DBG (1, "define scan mode failed: %s\n", sane_strstatus (status));
1480      return (status);
1481    }
1482
1483  DBG (3, "sane_start: sending GET SCAN MODE for scan control conditions\n");
1484  memset (ebuf, 0, sizeof (ebuf));
1485  buf_size = sizeof (ebuf);
1486  status = get_scan_mode (s->fd, SCAN_CONTROL_CONDITIONS, ebuf, &buf_size);
1487  if (status != SANE_STATUS_GOOD)
1488    {
1489      DBG (1, "sane_start: GET SCAN MODE for scan control conditions "
1490	"failed\n");
1491      sanei_scsi_close (s->fd);
1492      return (SANE_STATUS_INVAL);
1493    }
1494  for (i = 0; i < buf_size; i++)
1495    DBG (3, "scan mode byte[%d] = %d\n", (int) i, ebuf[i]);
1496
1497  /* Focus, but not for previews or negatives with speed control */
1498  if (SANE_OPTION_IS_ACTIVE(s->opt[OPT_FOCUS_GROUP].cap)
1499    && !s->val[OPT_PREVIEW].w && s->AF_NOW
1500    && (s->RIF || s->AE || s->scanning_speed == 0))
1501    {
1502      if ((status = do_focus (s)) != SANE_STATUS_GOOD) return (status);
1503      if (s->val[OPT_AF_ONCE].w) s->AF_NOW = SANE_FALSE;
1504    }
1505
1506  /* ============= modification for FB620S ============= */
1507  DBG (3, "TEST_UNIT_READY\n");
1508  status = test_unit_ready (s->fd);
1509  if (status != SANE_STATUS_GOOD)
1510    {
1511      DBG (1, "test unit ready failed (%s)\n", sane_strstatus (status));
1512      sanei_scsi_close (s->fd);
1513      s->fd = -1;
1514      return (status);
1515    }
1516
1517  if (s->hw->info.can_calibrate)
1518    {
1519      DBG (3, "sane_start: sending GET_CALIBRATION_STATUS\n");
1520      buf_size = sizeof (cbuf);
1521      memset (cbuf, 0, buf_size);
1522      status = get_calibration_status (s->fd, cbuf, &buf_size);
1523      if (status != SANE_STATUS_GOOD)
1524	{
1525	  DBG (1, "sane_start: GET_CALIBRATION_STATUS failed: %s\n",
1526	       sane_strstatus (status));
1527	  sanei_scsi_close (s->fd);
1528	  s->fd = -1;
1529	  return (status);
1530	}
1531
1532      DBG (1, "cbuf[0] = %d\n", cbuf[0]);
1533      DBG (1, "cbuf[1] = %d\n", cbuf[1]);
1534
1535      cbuf[0] &= 3;
1536      if (cbuf[0] == 1 || cbuf[0] == 2 || cbuf[0] == 3)
1537	{
1538	  status = execute_calibration (s->fd);
1539	  DBG (3, "sane_start: EXECUTE_CALIBRATION\n");
1540	  if (status != SANE_STATUS_GOOD)
1541	    {
1542	      DBG (1, "sane_start: EXECUTE_CALIBRATION failed\n");
1543	      sanei_scsi_close (s->fd);
1544	      s->fd = -1;
1545	      return (status);
1546	    }
1547
1548	  DBG (3, "after calibration: GET_CALIBRATION_STATUS\n");
1549	  buf_size = sizeof (cbuf);
1550	  memset (cbuf, 0, buf_size);
1551	  status = get_calibration_status (s->fd, cbuf, &buf_size);
1552	  if (status != SANE_STATUS_GOOD)
1553	    {
1554	      DBG (1, "after calibration: GET_CALIBRATION_STATUS failed: %s\n",
1555		sane_strstatus (status));
1556	      sanei_scsi_close (s->fd);
1557	      s->fd = -1;
1558	      return (status);
1559	    }
1560	  DBG (1, "cbuf[0] = %d\n", cbuf[0]);
1561	  DBG (1, "cbuf[1] = %d\n", cbuf[1]);
1562	}
1563    }
1564
1565  status = scan (s->fd);
1566  if (status != SANE_STATUS_GOOD)
1567    {
1568      DBG (1, "start of scan failed: %s\n", sane_strstatus (status));
1569      return (status);
1570    }
1571
1572  buf_size = sizeof (dbuf);
1573  memset (dbuf, 0, buf_size);
1574  status = get_data_status (s->fd, dbuf, &buf_size);
1575  if (status != SANE_STATUS_GOOD)
1576    {
1577      DBG (1, "GET DATA STATUS failed: %s\n", sane_strstatus (status));
1578      return (status);
1579    }
1580  DBG (5, ">> GET DATA STATUS\n");
1581  DBG (5, "Scan Data Available=%d\n", (dbuf[9] << 16) + (dbuf[10] << 8)
1582       + dbuf[11]);
1583  DBG (5, "Magnified Width=%d\n", (dbuf[12] <<24) + (dbuf[13] << 16)
1584       + (dbuf[14] << 8) + dbuf[15]);
1585  DBG (5, "Magnified Length=%d\n", (dbuf[16] << 24) + (dbuf[17] << 16)
1586       + (dbuf[18] << 8) + dbuf[19]);
1587  DBG (5, "Rest Data=%d bytes\n", (dbuf[20] << 24) + (dbuf[21] << 16)
1588       + (dbuf[22] << 8) + dbuf[23]);
1589  DBG (5, "Filled Data Buffer=%d\n", (dbuf[24] << 24) + (dbuf[25] << 16)
1590       + (dbuf[26] << 8) + dbuf[27]);
1591  DBG (5, "<< GET DATA STATUS\n");
1592
1593  s->bytes_to_read = s->params.bytes_per_line * s->params.lines;
1594
1595  if (s->hw->info.model == FB1200)
1596    {
1597      if (s->bytes_to_read != (((size_t) dbuf[9] << 16)
1598      + ((size_t) dbuf[10] << 8) + (size_t) dbuf[11]))
1599	{
1600	  s->params.bytes_per_line = (((size_t) dbuf[12] << 24)
1601	    + ((size_t) dbuf[13] << 16) + ((size_t) dbuf[14] << 8)
1602	    + (size_t)dbuf[15]);
1603	  s->params.lines = (((size_t) dbuf[16] << 24)
1604	    + ((size_t) dbuf[17] << 16) + ((size_t) dbuf[18] << 8)
1605	    + (size_t) dbuf[19]);
1606	  s->bytes_to_read = s->params.bytes_per_line * s->params.lines;
1607
1608	  mode_str = s->val[OPT_MODE].s;
1609	  if (!strcmp (mode_str, SANE_VALUE_SCAN_MODE_LINEART))
1610	    {
1611	      if (((600 < s->val[OPT_X_RESOLUTION].w)
1612		|| (600 < s->val[OPT_Y_RESOLUTION].w)))
1613		{
1614		  s->params.bytes_per_line *= 2;
1615		  s->params.lines /= 2;
1616		}
1617	      s->params.pixels_per_line = s->params.bytes_per_line * 8;
1618	    }
1619	  else if (!strcmp (mode_str, SANE_VALUE_SCAN_MODE_GRAY))
1620	      s->params.pixels_per_line = s->params.bytes_per_line;
1621	  else if (!strcmp (mode_str, SANE_VALUE_SCAN_MODE_COLOR)
1622	    || !strcmp (mode_str, SANE_I18N("Fine color")))
1623	      s->params.pixels_per_line = s->params.bytes_per_line / 3;
1624	  else
1625	    s->params.pixels_per_line = s->params.bytes_per_line / 6;
1626	}
1627    }
1628
1629  DBG (1, "%d pixels per line, %d bytes, %d lines high, total %lu bytes, "
1630       "dpi=%d\n", s->params.pixels_per_line, s->params.bytes_per_line,
1631       s->params.lines, (u_long) s->bytes_to_read,
1632       s->val[OPT_X_RESOLUTION].w);
1633
1634/**************************************************/
1635/* modification for FB620S and FB1200S */
1636  s->buf_used = 0;
1637  s->buf_pos = 0;
1638/**************************************************/
1639
1640  s->scanning = SANE_TRUE;
1641
1642  DBG (1, "<< sane_start\n");
1643  return (SANE_STATUS_GOOD);
1644}
1645
1646/**************************************************************************/
1647
1648static SANE_Status
1649sane_read_direct (SANE_Handle handle, SANE_Byte *buf, SANE_Int max_len,
1650		  SANE_Int *len)
1651{
1652  CANON_Scanner *s = handle;
1653  SANE_Status status;
1654  size_t nread;
1655
1656  DBG (21, ">> sane_read\n");
1657
1658  *len = 0;
1659  nread = max_len;
1660
1661  DBG (21, "   sane_read: nread=%d, bytes_to_read=%d\n", (int) nread,
1662  (int) s->bytes_to_read);
1663  if (s->bytes_to_read == 0)
1664    {
1665      do_cancel (s);
1666      return (SANE_STATUS_EOF);
1667    }
1668
1669  if (!s->scanning) return (do_cancel (s));
1670
1671  if (nread > s->bytes_to_read) nread = s->bytes_to_read;
1672  status = read_data (s->fd, buf, &nread);
1673  if (status != SANE_STATUS_GOOD)
1674    {
1675      do_cancel (s);
1676      return (SANE_STATUS_IO_ERROR);
1677    }
1678  *len = nread;
1679  s->bytes_to_read -= nread;
1680
1681  DBG (21, "   sane_read: nread=%d, bytes_to_read=%d\n", (int) nread,
1682  (int) s->bytes_to_read);
1683  DBG (21, "<< sane_read\n");
1684  return (SANE_STATUS_GOOD);
1685}
1686
1687/**************************************************************************/
1688
1689static SANE_Status
1690read_fs2710 (SANE_Handle handle, SANE_Byte *buf, SANE_Int max_len,
1691	     SANE_Int *len)
1692{
1693  CANON_Scanner *s = handle;
1694  SANE_Status status;
1695  int c;
1696  size_t i, nread, nread2;
1697  u_char *p;
1698#if defined(WORDS_BIGENDIAN)
1699  u_char b;
1700#endif
1701
1702  DBG (21, ">> sane_read\n");
1703
1704  *len = 0;
1705  nread = max_len;
1706
1707  DBG (21, "   sane_read: nread=%d, bytes_to_read=%d\n", (int) nread,
1708  (int) s->bytes_to_read);
1709
1710  if (nread > s->bytes_to_read) nread = s->bytes_to_read;
1711  if (s->bytes_to_read == 0)
1712    {
1713      do_cancel (s);
1714      return (SANE_STATUS_EOF);
1715    }
1716
1717  if (!s->scanning) return (do_cancel (s));
1718
1719  /* We must receive 2 little-endian bytes per pixel and colour.
1720     In raw mode we must swap the bytes if we are running a big-endian
1721     architecture (SANE standard 3.2.1), and pass them both.
1722     Otherwise the other subroutines expect only 1 byte, so we must
1723     set up an intermediate buffer which is twice as large
1724     as buf, and then map this buffer to buf. */
1725
1726  if (!strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR))
1727    {
1728      if (max_len > s->auxbuf_len)
1729	{				/* extend buffer? */
1730	  if (s->auxbuf_len > 0) free (s->auxbuf);
1731	  s->auxbuf_len = max_len;
1732	  if ((s->auxbuf = (u_char *) malloc (2 * max_len)) == NULL)
1733	    {
1734	      DBG (1, "sane_read buffer size insufficient\n");
1735	      do_cancel (s);
1736	      return SANE_STATUS_NO_MEM;
1737	    }
1738	}
1739
1740      nread2 = 2 * nread;
1741      if ((status = read_data (s->fd, s->auxbuf, &nread2)) != SANE_STATUS_GOOD)
1742	{
1743	  do_cancel (s);
1744	  return (SANE_STATUS_IO_ERROR);
1745	}
1746      nread = nread2 / 2;
1747      for (i = 0, p = s->auxbuf; i < nread; i++)
1748	{
1749	  c = *p++ >> 4;
1750	  c |= *p++ << 4;
1751	  *buf++ = s->gamma_map[s->colour++][c];
1752	  if (s->colour > 3) s->colour = 1;	/* cycle through RGB */
1753	}
1754    }
1755  else
1756    {
1757      if ((status = read_data (s->fd, buf, &nread)) != SANE_STATUS_GOOD)
1758	{
1759	  do_cancel (s);
1760	  return (SANE_STATUS_IO_ERROR);
1761	}
1762#if defined(WORDS_BIGENDIAN)
1763      for (p = buf; p < buf + nread; p++)
1764	{
1765	  b = *p;
1766	  *p = *(p + 1);
1767	  p++;
1768	  *p = b;
1769	}
1770#endif
1771    }
1772  *len = nread;
1773  s->bytes_to_read -= nread;
1774
1775  DBG (21, "   sane_read: nread=%d, bytes_to_read=%d\n", (int) nread,
1776  (int) s->bytes_to_read);
1777  DBG (21, "<< sane_read\n");
1778  return (SANE_STATUS_GOOD);
1779}
1780
1781/**************************************************************************/
1782/* modification for FB620S */
1783
1784static SANE_Status
1785read_fb620 (SANE_Handle handle, SANE_Byte *buf, SANE_Int max_len,
1786	    SANE_Int *len)
1787{
1788  CANON_Scanner *s = handle;
1789  SANE_Status status;
1790  SANE_Byte *out, *red, *green, *blue;
1791  SANE_Int ncopy;
1792  size_t nread = 0, i, pixel_per_line;
1793
1794  DBG (21, ">> read_fb620\n");
1795
1796  *len = 0;
1797
1798  DBG (21, "   read_fb620: nread=%d, bytes_to_read=%d\n", (int) nread,
1799  (int) s->bytes_to_read);
1800
1801  if (s->bytes_to_read == 0 && s->buf_pos == s->buf_used)
1802    {
1803      s->reset_flag = 0;	/* no reset */
1804
1805      do_cancel (s);
1806      DBG (21, "do_cancel(EOF)\n");
1807      DBG (21, "reset_flag = %d\n", s->reset_flag);
1808      return (SANE_STATUS_EOF);
1809    }
1810  else
1811    {
1812      s->reset_flag = 1;	/* do reset */
1813      DBG (21, "reset_flag = %d\n", s->reset_flag);
1814    }
1815  DBG (21, "   read_fb620: buf_pos=%d, buf_used=%d\n", s->buf_pos,
1816       s->buf_used);
1817
1818  if (!s->scanning)
1819    return (do_cancel (s));
1820
1821  if (s->buf_pos < s->buf_used)
1822    {
1823      ncopy = s->buf_used - s->buf_pos;
1824      if (ncopy > max_len)
1825	ncopy = max_len;
1826      memcpy (buf, &(s->outbuffer[s->buf_pos]), ncopy);
1827
1828      max_len -= ncopy;
1829      *len += ncopy;
1830      buf = &(buf[ncopy]);
1831      s->buf_pos += ncopy;
1832    }
1833
1834  if (s->buf_pos >= s->buf_used && s->bytes_to_read)
1835    {
1836      /* buffer is empty: read in scan line and sort color data as shown
1837         above */
1838
1839      nread = s->params.bytes_per_line;
1840
1841      if (nread > s->bytes_to_read)
1842	nread = s->bytes_to_read;
1843
1844      status = read_data (s->fd, s->inbuffer, &nread);
1845
1846      if (status != SANE_STATUS_GOOD)
1847	{
1848	  do_cancel (s);
1849	  return (SANE_STATUS_IO_ERROR);
1850	}
1851
1852      s->buf_used = s->params.bytes_per_line;
1853
1854      out = s->outbuffer;
1855      pixel_per_line = s->params.pixels_per_line;
1856
1857      red = s->inbuffer;
1858      green = &(s->inbuffer[pixel_per_line]);
1859      blue = &(s->inbuffer[2 * pixel_per_line]);
1860
1861      for (i = 0; i < pixel_per_line; i++)
1862	{
1863	  *out++ = *red++;
1864	  *out++ = *green++;
1865	  *out++ = *blue++;
1866	}
1867
1868      s->buf_pos = 0;
1869
1870      s->bytes_to_read -= s->buf_used;
1871
1872    }
1873
1874  if (max_len && s->buf_pos < s->buf_used)
1875    {
1876      ncopy = s->buf_used - s->buf_pos;
1877      if (ncopy > max_len)
1878	ncopy = max_len;
1879      memcpy (buf, &(s->outbuffer[s->buf_pos]), ncopy);
1880      *len += ncopy;
1881      s->buf_pos += ncopy;
1882    }
1883
1884  DBG (21, "<< read_fb620\n");
1885  return (SANE_STATUS_GOOD);
1886}
1887
1888/**************************************************************************/
1889/* modification for FB1200S */
1890
1891static SANE_Status
1892read_fb1200 (SANE_Handle handle, SANE_Byte *buf, SANE_Int max_len,
1893SANE_Int *len)
1894{
1895  CANON_Scanner *s = handle;
1896  SANE_Status status;
1897  SANE_Byte *firstimage, *secondimage/*, inmask, outmask, outbyte,
1898	    primaryHigh[256], primaryLow[256], secondaryHigh[256],
1899	    secondaryLow[256] */;
1900  SANE_Int ncopy;
1901  u_char dbuf[28];
1902  size_t buf_size, nread, remain, nwritten, nremain, pos, pix, pixel_per_line,
1903	 byte, byte_per_line/*, bit*/;
1904  ssize_t wres, readres;
1905  int maxpix;
1906
1907  DBG (21, ">> read_fb1200\n");
1908
1909  buf_size = sizeof (dbuf);
1910  memset (dbuf, 0, buf_size);
1911  status = get_data_status (s->fd, dbuf, &buf_size);
1912  if (status != SANE_STATUS_GOOD)
1913    {
1914      DBG (1, "GET DATA STATUS failed: %s\n", sane_strstatus (status));
1915      return (status);
1916    }
1917  DBG (5, ">> GET DATA STATUS\n");
1918  DBG (5, "Scan Data Available=%d\n", (dbuf[9] << 16) + (dbuf[10] << 8)
1919    + dbuf[11]);
1920  DBG (5, "Rest Data=%d bytes\n", (dbuf[20] << 24) + (dbuf[21] << 16)
1921    + (dbuf[22] << 8) + dbuf[23]);
1922  DBG (5, "Filled Data Buffer=%d\n", (dbuf[24] << 24) + (dbuf[25] << 16)
1923    + (dbuf[26] << 8) + dbuf[27]);
1924  DBG (5, "temp file position:%u\n", (unsigned int) lseek(s->tmpfile,
1925  0, SEEK_CUR));
1926  DBG (5, "<< GET DATA STATUS\n");
1927
1928  *len = 0;
1929
1930  DBG (21, "   read_fb1200: bytes_to_read=%d\n",
1931  (int) s->bytes_to_read);
1932
1933  if (s->bytes_to_read == 0 && s->buf_pos == s->buf_used)
1934    {
1935      do_cancel (s);
1936      DBG (21, "do_cancel(EOF)\n");
1937      return (SANE_STATUS_EOF);
1938    }
1939
1940  DBG (21, "   read_fb1200: buf_pos=%d, buf_used=%d\n", s->buf_pos,
1941       s->buf_used);
1942
1943  if (!s->scanning)
1944    return (do_cancel (s));
1945
1946  if (s->buf_pos >= s->buf_used && s->bytes_to_read)
1947    {
1948      nread = s->params.bytes_per_line / 2;
1949
1950      if (nread > s->bytes_to_read)
1951	nread = s->bytes_to_read;
1952
1953      status = read_data (s->fd, s->inbuffer, &nread);
1954
1955      if (status != SANE_STATUS_GOOD)
1956	{
1957	  do_cancel (s);
1958	  return (SANE_STATUS_IO_ERROR);
1959	}
1960
1961      /**** save the primary scan data to tmpfile ****/
1962
1963      if ((SANE_Int) s->bytes_to_read > s->params.bytes_per_line
1964	* s->params.lines / 2)
1965	{
1966	  remain = nread;
1967	  nwritten = 0;
1968	  while (remain)
1969	    {
1970	      errno = 0;
1971	      wres = write (s->tmpfile, &s->inbuffer[nwritten], remain);
1972	      if (wres == -1)
1973		{
1974		  DBG(1, "error write tmp file: %i, %s\n", errno,
1975		    strerror(errno));
1976		  do_cancel(s);
1977		  return (SANE_STATUS_NO_MEM);
1978		}
1979	      remain -= wres;
1980	      nwritten += wres;
1981	    }
1982
1983	  s->bytes_to_read -= nread;
1984
1985	  if ((SANE_Int) s->bytes_to_read <= s->params.bytes_per_line
1986	    * s->params.lines / 2)
1987	    {
1988	      if ((SANE_Int) s->bytes_to_read < s->params.bytes_per_line
1989		* s->params.lines / 2)
1990		DBG(1, "warning: read more data for the primary scan "
1991		  "than expected\n");
1992
1993	      lseek (s->tmpfile, 0L, SEEK_SET);
1994	      *len = 0;
1995	      *buf = 0;
1996	      return (SANE_STATUS_GOOD);
1997	    }
1998
1999	  DBG(1, "writing: the primary data to tmp file\n");
2000	  *len = 0;
2001	  *buf = 0;
2002	  return (SANE_STATUS_GOOD);
2003	}
2004      /** the primary scan data from tmpfile and the secondary scan data
2005	  are merged **/
2006
2007      s->buf_used = s->params.bytes_per_line;
2008      byte_per_line = s->params.bytes_per_line;
2009      pixel_per_line = s->params.pixels_per_line;
2010
2011
2012      /** read an entire scan line from the primary scan **/
2013
2014      remain = nread;
2015      pos = 0;
2016      firstimage = &(s->inbuffer[byte_per_line/2]);
2017
2018      while (remain > 0)
2019	{
2020	  nremain = (remain < SSIZE_MAX)? remain: SSIZE_MAX;
2021	  errno = 0;
2022	  readres = read (s->tmpfile, &(firstimage[pos]), nremain);
2023	  if (readres == -1)
2024	    {
2025	      DBG(1, "error reading tmp file: %i %s\n", errno,
2026		strerror(errno));
2027	      do_cancel(s);
2028	      return (SANE_STATUS_IO_ERROR);
2029	    }
2030	  if (readres == 0)
2031	    {
2032	      DBG(1, "0 byte read from temp file. premature EOF?\n");
2033	      return (SANE_STATUS_INVAL);
2034	      /* perhaps an error return? */
2035	    }
2036	  DBG(1, "reading: the primary data from tmp file\n");
2037	  remain -= readres;
2038	  pos += readres;
2039	}
2040
2041      secondimage = s->inbuffer;
2042
2043      if (!strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR))
2044	{
2045	  maxpix = pixel_per_line / 2;
2046	  for (pix = 0; (int) pix < maxpix; pix++)
2047	    {
2048	      s->outbuffer[6 * pix] = secondimage[3 * pix];
2049	      s->outbuffer[6 * pix + 1] = secondimage[3 * pix + 1];
2050	      s->outbuffer[6 * pix + 2] = secondimage[3 * pix + 2];
2051	      s->outbuffer[6 * pix + 3] = firstimage[3 * pix];
2052	      s->outbuffer[6 * pix + 4] = firstimage[3 * pix + 1];
2053	      s->outbuffer[6 * pix + 5] = firstimage[3 * pix + 2];
2054	    }
2055	}
2056      else if (!strcmp (s->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY))
2057	{
2058	  for (pix = 0; pix < pixel_per_line / 2; pix++)
2059	    {
2060	      s->outbuffer[2 * pix] = secondimage[pix];
2061	      s->outbuffer[2 * pix + 1] = firstimage[pix];
2062	    }
2063	}
2064      else /* for lineart mode */
2065	{
2066	  maxpix = byte_per_line / 2;
2067	  for (byte = 0; (int) byte < maxpix; byte++)
2068	    {
2069	      s->outbuffer[2 * byte] = primaryHigh[firstimage[byte]]
2070		| secondaryHigh[secondimage[byte]];
2071	      s->outbuffer[2 * byte + 1] = primaryLow[firstimage[byte]]
2072		| secondaryLow[secondimage[byte]];
2073#if 0
2074	      inmask = 128;
2075	      outmask = 128;
2076	      outbyte = 0;
2077	      for (bit = 0; bit < 4; bit++)
2078		{
2079		  if (inmask == (secondimage[byte] & inmask))
2080		    outbyte = outbyte | outmask;
2081		  outmask = outmask >> 1;
2082		  if (inmask == (firstimage[byte] & inmask))
2083		    outbyte = outbyte | outmask;
2084		  outmask = outmask >> 1;
2085		  inmask = inmask >> 1;
2086		}
2087	      s->outbuffer[2 * byte] = outbyte;
2088
2089	      outmask = 128;
2090	      outbyte = 0;
2091	      for (bit = 0; bit < 4; bit++)
2092		{
2093		  if (inmask == (secondimage[byte] & inmask))
2094		    outbyte = outbyte | outmask;
2095		  outmask = outmask >> 1;
2096		  if (inmask == (firstimage[byte] & inmask))
2097		    outbyte = outbyte | outmask;
2098		  outmask = outmask >> 1;
2099		  inmask = inmask >> 1;
2100		}
2101	      s->outbuffer[2 * byte + 1] = outbyte;
2102#endif
2103	    }
2104	}
2105
2106      s->buf_pos = 0;
2107      s->bytes_to_read -= nread;
2108    }
2109
2110  if (max_len && s->buf_pos < s->buf_used)
2111    {
2112      ncopy = s->buf_used - s->buf_pos;
2113      if (ncopy > max_len)
2114	ncopy = max_len;
2115      memcpy (buf, &(s->outbuffer[s->buf_pos]), ncopy * 2);
2116      *len += ncopy;
2117      s->buf_pos += ncopy;
2118    }
2119
2120  DBG (21, "<< read_fb1200\n");
2121  return (SANE_STATUS_GOOD);
2122}
2123
2124/**************************************************************************/
2125SANE_Status
2126sane_read (SANE_Handle handle, SANE_Byte *buf, SANE_Int max_len,
2127	   SANE_Int *len)
2128{
2129  CANON_Scanner *s = handle;
2130  SANE_Status status;
2131  if (s->hw->info.model == FB620 && s->params.format == SANE_FRAME_RGB)
2132    status = read_fb620 (handle, buf, max_len, len);
2133  else if (s->hw->info.model == FS2710)
2134    status = read_fs2710 (handle, buf, max_len, len);
2135  else if (s->hw->info.model == FB1200 && ((600 < s->val[OPT_X_RESOLUTION].w)
2136    || (600 < s->val[OPT_Y_RESOLUTION].w)))
2137    status = read_fb1200 (handle, buf, max_len, len);
2138  else
2139    status = sane_read_direct (handle, buf, max_len, len);
2140  if (s->time0 == -1)
2141    s->time0 = 0;
2142  else
2143    time (&(s->time0));
2144
2145  DBG (11, "sane_read: time0 = %ld\n", s->time0);
2146  s->switch_preview = s->val[OPT_PREVIEW].w;
2147  return (status);
2148}
2149
2150/**************************************************************************/
2151
2152void
2153sane_cancel (SANE_Handle handle)
2154{
2155  CANON_Scanner *s = handle;
2156  DBG (1, ">> sane_cancel\n");
2157
2158/******** for FB1200S ************/
2159  if(s->hw->info.model == FB1200)
2160   {
2161    if (s->tmpfile != -1)
2162     {
2163      close (s->tmpfile);
2164      DBG(1, " ****** tmpfile is closed ****** \n");
2165     }
2166    else
2167     {
2168      DBG(1, "tmpfile is failed\n");
2169/*    return (SANE_STATUS_INVAL);*/
2170     }
2171   }
2172/*********************************/
2173
2174  s->scanning = SANE_FALSE;
2175  DBG (1, "<< sane_cancel\n");
2176}
2177
2178/**************************************************************************/
2179
2180SANE_Status
2181sane_set_io_mode (SANE_Handle __sane_unused__ handle,
2182SANE_Bool __sane_unused__ non_blocking)
2183{
2184  DBG (1, ">> sane_set_io_mode\n");
2185  DBG (1, "<< sane_set_io_mode\n");
2186  return SANE_STATUS_UNSUPPORTED;
2187}
2188
2189/**************************************************************************/
2190
2191SANE_Status
2192sane_get_select_fd (SANE_Handle __sane_unused__ handle,
2193SANE_Int __sane_unused__ * fd)
2194{
2195  DBG (1, ">> sane_get_select_fd\n");
2196  DBG (1, "<< sane_get_select_fd\n");
2197
2198  return SANE_STATUS_UNSUPPORTED;
2199}
2200
2201/**************************************************************************/
2202