1 /* sane - Scanner Access Now Easy.
2    Copyright (C) 1999 Juergen G. Schimmer
3    Updates and bugfixes (C) 2002 - 2004 Henning Meier-Geinitz
4 
5    This file is part of the SANE package.
6 
7    This program is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License as
9    published by the Free Software Foundation; either version 2 of the
10    License, or (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <https://www.gnu.org/licenses/>.
19 
20    As a special exception, the authors of SANE give permission for
21    additional uses of the libraries contained in this release of SANE.
22 
23    The exception is that, if you link a SANE library with other files
24    to produce an executable, this does not by itself cause the
25    resulting executable to be covered by the GNU General Public
26    License.  Your use of that executable is in no way restricted on
27    account of linking the SANE library code into it.
28 
29    This exception does not, however, invalidate any other reasons why
30    the executable file might be covered by the GNU General Public
31    License.
32 
33    If you submit changes to SANE to the maintainers to be included in
34    a subsequent release, you agree by submitting the changes that
35    those changes may be distributed with this exception intact.
36 
37    If you write modifications of your own for SANE, it is your choice
38    whether to permit this exception to apply to your modifications.
39    If you do not wish that, delete this exception notice.
40 
41    This file implements a SANE backend for v4l-Devices.
42 */
43 
44 #define BUILD 5
45 
46 #include "../include/sane/config.h"
47 
48 #include <assert.h>
49 #include <ctype.h>
50 #include <errno.h>
51 #include <fcntl.h>
52 #include <limits.h>
53 #include <math.h>
54 #include <setjmp.h>
55 #include <signal.h>
56 #include <stdio.h>
57 #include <stdlib.h>
58 #include <string.h>
59 #include <sys/types.h>
60 #include <sys/wait.h>
61 #include <unistd.h>
62 #include <sys/mman.h>
63 
64 #include <unistd.h>
65 #include <sys/time.h>
66 #include <sys/stat.h>
67 
68 #include "../include/sane/sane.h"
69 #include "../include/sane/sanei.h"
70 #include "../include/sane/saneopts.h"
71 
72 #include <sys/ioctl.h>
73 
74 #define BACKEND_NAME v4l
75 #include "../include/sane/sanei_backend.h"
76 
77 #ifndef PATH_MAX
78 # define PATH_MAX       1024
79 #endif
80 
81 #include "../include/sane/sanei_config.h"
82 #define V4L_CONFIG_FILE "v4l.conf"
83 
84 #include <libv4l1.h>
85 #include "v4l.h"
86 
87 static const SANE_Device **devlist = NULL;
88 static int num_devices;
89 static V4L_Device *first_dev;
90 static V4L_Scanner *first_handle;
91 static char *buffer;
92 
93 static const SANE_String_Const mode_list[] = {
94   SANE_VALUE_SCAN_MODE_GRAY, SANE_VALUE_SCAN_MODE_COLOR,
95   0
96 };
97 
98 static const SANE_Range u8_range = {
99   /* min, max, quantization */
100   0, 255, 0
101 };
102 
103 static SANE_Range x_range = { 0, 338, 2 };
104 
105 static SANE_Range odd_x_range = { 1, 339, 2 };
106 
107 static SANE_Range y_range = { 0, 249, 1 };
108 
109 static SANE_Range odd_y_range = { 1, 250, 1 };
110 
111 
112 static SANE_Parameters parms = {
113   SANE_FRAME_RGB,
114   1,				/* 1 = Last Frame , 0 = More Frames to come */
115   0,				/* Number of bytes returned per scan line: */
116   0,				/* Number of pixels per scan line.  */
117   0,				/* Number of lines for the current scan.  */
118   8,				/* Number of bits per sample. */
119 };
120 
121 static SANE_Status
attach(const char *devname, V4L_Device ** devp)122 attach (const char *devname, V4L_Device ** devp)
123 {
124   V4L_Device *dev;
125   static int v4lfd;
126   static struct video_capability capability;
127 
128   errno = 0;
129 
130   for (dev = first_dev; dev; dev = dev->next)
131     if (strcmp (dev->sane.name, devname) == 0)
132       {
133 	if (devp)
134 	  *devp = dev;
135 	DBG (5, "attach: device %s is already known\n", devname);
136 	return SANE_STATUS_GOOD;
137       }
138 
139   DBG (3, "attach: trying to open %s\n", devname);
140   v4lfd = v4l1_open (devname, O_RDWR);
141   if (v4lfd != -1)
142     {
143       if (v4l1_ioctl (v4lfd, VIDIOCGCAP, &capability) == -1)
144 	{
145 	  DBG (1,
146 	       "attach: ioctl (%d, VIDIOCGCAP,..) failed on `%s': %s\n",
147 	       v4lfd, devname, strerror (errno));
148 	  v4l1_close (v4lfd);
149 	  return SANE_STATUS_INVAL;
150 	}
151       if (!(VID_TYPE_CAPTURE & capability.type))
152 	{
153 	  DBG (1, "attach: device %s can't capture to memory -- exiting\n",
154 	       devname);
155 	  v4l1_close (v4lfd);
156 	  return SANE_STATUS_UNSUPPORTED;
157 	}
158       DBG (2, "attach: found videodev `%s' on `%s'\n", capability.name,
159 	   devname);
160       v4l1_close (v4lfd);
161     }
162   else
163     {
164       DBG (1, "attach: failed to open device `%s': %s\n", devname,
165 	   strerror (errno));
166       return SANE_STATUS_INVAL;
167     }
168 
169   dev = malloc (sizeof (*dev));
170   if (!dev)
171     return SANE_STATUS_NO_MEM;
172 
173   memset (dev, 0, sizeof (*dev));
174 
175   dev->sane.name = strdup (devname);
176   if (!dev->sane.name)
177     return SANE_STATUS_NO_MEM;
178   dev->sane.vendor = "Noname";
179   dev->sane.model = strdup (capability.name);
180   if (!dev->sane.model)
181     return SANE_STATUS_NO_MEM;
182   dev->sane.type = "virtual device";
183 
184   ++num_devices;
185   dev->next = first_dev;
186   first_dev = dev;
187 
188   if (devp)
189     *devp = dev;
190   return SANE_STATUS_GOOD;
191 }
192 
193 static void
update_parameters(V4L_Scanner * s)194 update_parameters (V4L_Scanner * s)
195 {
196   /* ??? should be per-device */
197   x_range.min = 0;
198   x_range.max = s->capability.maxwidth - s->capability.minwidth;
199   x_range.quant = 1;
200 
201   y_range.min = 0;
202   y_range.max = s->capability.maxheight - s->capability.minheight;
203   y_range.quant = 1;
204 
205   odd_x_range.min = s->capability.minwidth;
206   odd_x_range.max = s->capability.maxwidth;
207   if (odd_x_range.max > 767)
208     {
209       odd_x_range.max = 767;
210       x_range.max = 767 - s->capability.minwidth;
211     };
212   odd_x_range.quant = 1;
213 
214   odd_y_range.min = s->capability.minheight;
215   odd_y_range.max = s->capability.maxheight;
216   if (odd_y_range.max > 511)
217     {
218       odd_y_range.max = 511;
219       y_range.max = 511 - s->capability.minheight;
220     };
221   odd_y_range.quant = 1;
222 
223   parms.lines = s->window.height;
224   parms.pixels_per_line = s->window.width;
225 
226   switch (s->pict.palette)
227     {
228     case VIDEO_PALETTE_GREY:	/* Linear greyscale */
229       {
230 	parms.format = SANE_FRAME_GRAY;
231 	parms.depth = 8;
232 	parms.bytes_per_line = s->window.width;
233 	break;
234       }
235     case VIDEO_PALETTE_RGB24:	/* 24bit RGB */
236       {
237 	parms.format = SANE_FRAME_RGB;
238 	parms.depth = 8;
239 	parms.bytes_per_line = s->window.width * 3;
240 	break;
241       }
242     default:
243       {
244 	parms.format = SANE_FRAME_GRAY;
245 	parms.bytes_per_line = s->window.width;
246 	break;
247       }
248     }
249 }
250 
251 static SANE_Status
init_options(V4L_Scanner * s)252 init_options (V4L_Scanner * s)
253 {
254   int i;
255 
256   memset (s->opt, 0, sizeof (s->opt));
257   memset (s->val, 0, sizeof (s->val));
258 
259   for (i = 0; i < NUM_OPTIONS; ++i)
260     {
261       s->opt[i].size = sizeof (SANE_Word);
262       s->opt[i].cap = (SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT);
263     }
264 
265   /* Number of options */
266   s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
267   s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
268   s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
269   s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
270   s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
271 
272   /* "Mode" group: */
273   s->opt[OPT_MODE_GROUP].title = "Scan Mode";
274   s->opt[OPT_MODE_GROUP].desc = "";
275   s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
276   s->opt[OPT_MODE_GROUP].cap = 0;
277   s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
278 
279   /* mode */
280   s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
281   s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
282   s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
283   s->opt[OPT_MODE].type = SANE_TYPE_STRING;
284   s->opt[OPT_MODE].unit = SANE_UNIT_NONE;
285   s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
286   s->opt[OPT_MODE].constraint.string_list = mode_list;
287   s->val[OPT_MODE].s = strdup (mode_list[0]);
288   if (!s->val[OPT_MODE].s)
289     return SANE_STATUS_NO_MEM;
290   s->opt[OPT_MODE].size = 1; /* '\0' */
291   for (i = 0; mode_list[i] != 0; ++i)
292     {
293       int len = strlen(mode_list[i]) + 1;
294       if (s->opt[OPT_MODE].size < len)
295         s->opt[OPT_MODE].size = len;
296     }
297 
298   /* channel */
299   s->opt[OPT_CHANNEL].name = "channel";
300   s->opt[OPT_CHANNEL].title = "Channel";
301   s->opt[OPT_CHANNEL].desc =
302     "Selects the channel of the v4l device (e.g. television " "or video-in.";
303   s->opt[OPT_CHANNEL].type = SANE_TYPE_STRING;
304   s->opt[OPT_CHANNEL].unit = SANE_UNIT_NONE;
305   s->opt[OPT_CHANNEL].constraint_type = SANE_CONSTRAINT_STRING_LIST;
306   s->opt[OPT_CHANNEL].constraint.string_list = s->channel;
307   s->val[OPT_CHANNEL].s = strdup (s->channel[0]);
308   if (!s->val[OPT_CHANNEL].s)
309     return SANE_STATUS_NO_MEM;
310   if (s->channel[0] == 0 || s->channel[1] == 0)
311     s->opt[OPT_CHANNEL].cap |= SANE_CAP_INACTIVE;
312   s->opt[OPT_CHANNEL].size = 1; /* '\0' */
313   for (i = 0; s->channel[i] != 0; ++i)
314     {
315       int len = strlen(s->channel[i]) + 1;
316       if (s->opt[OPT_CHANNEL].size < len)
317         s->opt[OPT_CHANNEL].size = len;
318     }
319 
320   /* "Geometry" group: */
321   s->opt[OPT_GEOMETRY_GROUP].title = "Geometry";
322   s->opt[OPT_GEOMETRY_GROUP].desc = "";
323   s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
324   s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
325   s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
326 
327 /* top-left x *//* ??? first check if window is settable at all */
328   s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
329   s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
330   s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
331   s->opt[OPT_TL_X].type = SANE_TYPE_INT;
332   s->opt[OPT_TL_X].unit = SANE_UNIT_PIXEL;
333   s->opt[OPT_TL_X].cap |= SANE_CAP_INACTIVE;
334   s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
335   s->opt[OPT_TL_X].constraint.range = &x_range;
336   s->val[OPT_TL_X].w = 0;
337 
338   /* top-left y */
339   s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
340   s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
341   s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
342   s->opt[OPT_TL_Y].type = SANE_TYPE_INT;
343   s->opt[OPT_TL_Y].unit = SANE_UNIT_PIXEL;
344   s->opt[OPT_TL_Y].cap |= SANE_CAP_INACTIVE;
345   s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
346   s->opt[OPT_TL_Y].constraint.range = &y_range;
347   s->val[OPT_TL_Y].w = 0;
348 
349   /* bottom-right x */
350   s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
351   s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
352   s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
353   s->opt[OPT_BR_X].type = SANE_TYPE_INT;
354   s->opt[OPT_BR_X].unit = SANE_UNIT_PIXEL;
355   s->opt[OPT_BR_X].cap |= SANE_CAP_INACTIVE;
356   s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
357   s->opt[OPT_BR_X].constraint.range = &odd_x_range;
358   s->val[OPT_BR_X].w = s->capability.maxwidth;
359   if (s->val[OPT_BR_X].w > 767)
360     s->val[OPT_BR_X].w = 767;
361 
362   /* bottom-right y */
363   s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
364   s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
365   s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
366   s->opt[OPT_BR_Y].type = SANE_TYPE_INT;
367   s->opt[OPT_BR_Y].unit = SANE_UNIT_PIXEL;
368   s->opt[OPT_BR_Y].cap |= SANE_CAP_INACTIVE;
369   s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
370   s->opt[OPT_BR_Y].constraint.range = &odd_y_range;
371   s->val[OPT_BR_Y].w = s->capability.maxheight;
372   if (s->val[OPT_BR_Y].w > 511)
373     s->val[OPT_BR_Y].w = 511;
374 
375   /* "Enhancement" group: */
376   s->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement";
377   s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
378   s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
379   s->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
380   s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
381 
382   /* brightness */
383   s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
384   s->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
385   s->opt[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS;
386   s->opt[OPT_BRIGHTNESS].type = SANE_TYPE_INT;
387   s->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
388   s->opt[OPT_BRIGHTNESS].constraint.range = &u8_range;
389   s->val[OPT_BRIGHTNESS].w = s->pict.brightness / 256;
390 
391   /* hue */
392   s->opt[OPT_HUE].name = SANE_NAME_HUE;
393   s->opt[OPT_HUE].title = SANE_TITLE_HUE;
394   s->opt[OPT_HUE].desc = SANE_DESC_HUE;
395   s->opt[OPT_HUE].type = SANE_TYPE_INT;
396   s->opt[OPT_HUE].constraint_type = SANE_CONSTRAINT_RANGE;
397   s->opt[OPT_HUE].constraint.range = &u8_range;
398   s->val[OPT_HUE].w = s->pict.hue / 256;
399 
400   /* colour */
401   s->opt[OPT_COLOR].name = "color";
402   s->opt[OPT_COLOR].title = "Picture color";
403   s->opt[OPT_COLOR].desc = "Sets the picture's color.";
404   s->opt[OPT_COLOR].type = SANE_TYPE_INT;
405   s->opt[OPT_COLOR].constraint_type = SANE_CONSTRAINT_RANGE;
406   s->opt[OPT_COLOR].constraint.range = &u8_range;
407   s->val[OPT_COLOR].w = s->pict.colour / 256;
408 
409   /* contrast */
410   s->opt[OPT_CONTRAST].name = SANE_NAME_CONTRAST;
411   s->opt[OPT_CONTRAST].title = SANE_TITLE_CONTRAST;
412   s->opt[OPT_CONTRAST].desc = SANE_DESC_CONTRAST;
413   s->opt[OPT_CONTRAST].type = SANE_TYPE_INT;
414   s->opt[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
415   s->opt[OPT_CONTRAST].constraint.range = &u8_range;
416   s->val[OPT_CONTRAST].w = s->pict.contrast / 256;
417 
418   /* whiteness */
419   s->opt[OPT_WHITE_LEVEL].name = SANE_NAME_WHITE_LEVEL;
420   s->opt[OPT_WHITE_LEVEL].title = SANE_TITLE_WHITE_LEVEL;
421   s->opt[OPT_WHITE_LEVEL].desc = SANE_DESC_WHITE_LEVEL;
422   s->opt[OPT_WHITE_LEVEL].type = SANE_TYPE_INT;
423   s->opt[OPT_WHITE_LEVEL].constraint_type = SANE_CONSTRAINT_RANGE;
424   s->opt[OPT_WHITE_LEVEL].constraint.range = &u8_range;
425   s->val[OPT_WHITE_LEVEL].w = s->pict.whiteness / 256;
426 
427   return SANE_STATUS_GOOD;
428 }
429 
430 SANE_Status
sane_init(SANE_Int * version_code, SANE_Auth_Callback authorize)431 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
432 {
433   char dev_name[PATH_MAX], *str;
434   size_t len;
435   FILE *fp;
436 
437   (void) authorize;		/* stop gcc from complaining */
438   DBG_INIT ();
439 
440   DBG (2, "SANE v4l backend version %d.%d build %d from %s\n", SANE_CURRENT_MAJOR,
441        SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING);
442 
443   if (version_code)
444     *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD);
445 
446   fp = sanei_config_open (V4L_CONFIG_FILE);
447   if (!fp)
448     {
449       DBG (2,
450 	   "sane_init: file `%s' not accessible (%s), trying /dev/video0\n",
451 	   V4L_CONFIG_FILE, strerror (errno));
452 
453       return attach ("/dev/video0", 0);
454     }
455 
456   while (sanei_config_read (dev_name, sizeof (dev_name), fp))
457     {
458       if (dev_name[0] == '#')	/* ignore line comments */
459 	continue;
460       len = strlen (dev_name);
461 
462       if (!len)
463 	continue;		/* ignore empty lines */
464 
465       /* Remove trailing space and trailing comments */
466       for (str = dev_name; *str && !isspace (*str) && *str != '#'; ++str);
467       attach (dev_name, 0);
468     }
469   fclose (fp);
470   return SANE_STATUS_GOOD;
471 }
472 
473 void
sane_exit(void)474 sane_exit (void)
475 {
476   V4L_Device *dev, *next;
477 
478   for (dev = first_dev; dev; dev = next)
479     {
480       next = dev->next;
481       free ((void *) dev->sane.name);
482       free ((void *) dev->sane.model);
483       free (dev);
484     }
485 
486   if (NULL != devlist)
487     {
488       free (devlist);
489       devlist = NULL;
490     }
491   DBG (5, "sane_exit: all devices freed\n");
492 }
493 
494 SANE_Status
sane_get_devices(const SANE_Device *** device_list, SANE_Bool __sane_unused__ local_only)495 sane_get_devices (const SANE_Device *** device_list, SANE_Bool __sane_unused__ local_only)
496 {
497   V4L_Device *dev;
498   int i;
499 
500   DBG (5, "sane_get_devices\n");
501 
502   if (devlist)
503     free (devlist);
504 
505   devlist = malloc ((num_devices + 1) * sizeof (devlist[0]));
506   if (!devlist)
507     return SANE_STATUS_NO_MEM;
508 
509   i = 0;
510   for (dev = first_dev; i < num_devices; dev = dev->next)
511     devlist[i++] = &dev->sane;
512   devlist[i++] = 0;
513 
514   *device_list = devlist;
515   return SANE_STATUS_GOOD;
516 }
517 
518 SANE_Status
sane_open(SANE_String_Const devname, SANE_Handle * handle)519 sane_open (SANE_String_Const devname, SANE_Handle * handle)
520 {
521   V4L_Device *dev;
522   V4L_Scanner *s;
523   static int v4lfd;
524   int i;
525   struct video_channel channel;
526   SANE_Status status;
527   int max_channels = MAX_CHANNELS;
528 
529   if (!devname)
530     {
531       DBG (1, "sane_open: devname == 0\n");
532       return SANE_STATUS_INVAL;
533     }
534 
535   for (dev = first_dev; dev; dev = dev->next)
536     if (strcmp (dev->sane.name, devname) == 0)
537       {
538 	DBG (5, "sane_open: device %s found in devlist\n", devname);
539 	break;
540       }
541   if (!devname[0])
542     dev = first_dev;
543   if (!dev)
544     {
545       DBG (1, "sane_open: device %s doesn't seem to be a v4l "
546 	   "device\n", devname);
547       return SANE_STATUS_INVAL;
548     }
549 
550   v4lfd = v4l1_open (devname, O_RDWR);
551   if (v4lfd == -1)
552     {
553       DBG (1, "sane_open: can't open %s (%s)\n", devname, strerror (errno));
554       return SANE_STATUS_INVAL;
555     }
556   s = malloc (sizeof (*s));
557   if (!s)
558     return SANE_STATUS_NO_MEM;
559   memset (s, 0, sizeof (*s));
560   s->user_corner = 0;		/* ??? */
561   s->devicename = devname;
562   s->fd = v4lfd;
563 
564   if (v4l1_ioctl (s->fd, VIDIOCGCAP, &s->capability) == -1)
565     {
566       DBG (1, "sane_open: ioctl (%d, VIDIOCGCAP,..) failed on `%s': %s\n",
567 	   s->fd, devname, strerror (errno));
568       v4l1_close (s->fd);
569       return SANE_STATUS_INVAL;
570     }
571 
572   DBG (5, "sane_open: %d channels, %d audio devices\n",
573        s->capability.channels, s->capability.audios);
574   DBG (5, "sane_open: minwidth=%d, minheight=%d, maxwidth=%d, "
575        "maxheight=%d\n", s->capability.minwidth, s->capability.minheight,
576        s->capability.maxwidth, s->capability.maxheight);
577   if (VID_TYPE_CAPTURE & s->capability.type)
578     DBG (5, "sane_open: V4L device can capture to memory\n");
579   if (VID_TYPE_TUNER & s->capability.type)
580     DBG (5, "sane_open: V4L device has a tuner of some form\n");
581   if (VID_TYPE_TELETEXT & s->capability.type)
582     DBG (5, "sane_open: V4L device supports teletext\n");
583   if (VID_TYPE_OVERLAY & s->capability.type)
584     DBG (5, "sane_open: V4L device can overlay its image onto the frame "
585 	 "buffer\n");
586   if (VID_TYPE_CHROMAKEY & s->capability.type)
587     DBG (5, "sane_open: V4L device uses chromakey on overlay\n");
588   if (VID_TYPE_CLIPPING & s->capability.type)
589     DBG (5, "sane_open: V4L device supports overlay clipping\n");
590   if (VID_TYPE_FRAMERAM & s->capability.type)
591     DBG (5, "sane_open: V4L device overwrites frame buffer memory\n");
592   if (VID_TYPE_SCALES & s->capability.type)
593     DBG (5, "sane_open: V4L device supports hardware scaling\n");
594   if (VID_TYPE_MONOCHROME & s->capability.type)
595     DBG (5, "sane_open: V4L device is grey scale only\n");
596   if (VID_TYPE_SUBCAPTURE & s->capability.type)
597     DBG (5, "sane_open: V4L device can capture parts of the image\n");
598 
599   if (s->capability.channels < max_channels)
600     max_channels = s->capability.channels;
601   for (i = 0; i < max_channels; i++)
602     {
603       channel.channel = i;
604       if (-1 == v4l1_ioctl (v4lfd, VIDIOCGCHAN, &channel))
605 	{
606 	  DBG (1, "sane_open: can't ioctl VIDIOCGCHAN %s: %s\n", devname,
607 	       strerror (errno));
608 	  return SANE_STATUS_INVAL;
609 	}
610       DBG (5, "sane_open: channel %d (%s), tuners=%d, flags=0x%x, "
611 	   "type=%d, norm=%d\n", channel.channel, channel.name,
612 	   channel.tuners, channel.flags, channel.type, channel.norm);
613       if (VIDEO_VC_TUNER & channel.flags)
614 	DBG (5, "sane_open: channel has tuner(s)\n");
615       if (VIDEO_VC_AUDIO & channel.flags)
616 	DBG (5, "sane_open: channel has audio\n");
617       if (VIDEO_TYPE_TV == channel.type)
618 	DBG (5, "sane_open: input is TV input\n");
619       if (VIDEO_TYPE_CAMERA == channel.type)
620 	DBG (5, "sane_open: input is camera input\n");
621       s->channel[i] = strdup (channel.name);
622       if (!s->channel[i])
623 	return SANE_STATUS_NO_MEM;
624     }
625   s->channel[i] = 0;
626   if (-1 == v4l1_ioctl (v4lfd, VIDIOCGPICT, &s->pict))
627     {
628       DBG (1, "sane_open: can't ioctl VIDIOCGPICT %s: %s\n", devname,
629 	   strerror (errno));
630       return SANE_STATUS_INVAL;
631     }
632   DBG (5, "sane_open: brightness=%d, hue=%d, colour=%d, contrast=%d\n",
633        s->pict.brightness, s->pict.hue, s->pict.colour, s->pict.contrast);
634   DBG (5, "sane_open: whiteness=%d, depth=%d, palette=%d\n",
635        s->pict.whiteness, s->pict.depth, s->pict.palette);
636 
637   /* ??? */
638   s->pict.palette = VIDEO_PALETTE_GREY;
639   if (-1 == v4l1_ioctl (s->fd, VIDIOCSPICT, &s->pict))
640     {
641       DBG (1, "sane_open: ioctl VIDIOCSPICT failed (%s)\n", strerror (errno));
642     }
643 
644   if (-1 == v4l1_ioctl (s->fd, VIDIOCGWIN, &s->window))
645     {
646       DBG (1, "sane_open: can't ioctl VIDIOCGWIN %s: %s\n", devname,
647 	   strerror (errno));
648       return SANE_STATUS_INVAL;
649     }
650   DBG (5, "sane_open: x=%d, y=%d, width=%d, height=%d\n",
651        s->window.x, s->window.y, s->window.width, s->window.height);
652 
653   /* already done in sane_start
654      if (-1 == v4l1_ioctl (v4lfd, VIDIOCGMBUF, &mbuf))
655      DBG (1, "sane_open: can't ioctl VIDIOCGMBUF (no Fbuffer?)\n");
656    */
657 
658   status = init_options (s);
659   if (status != SANE_STATUS_GOOD)
660     return status;
661   update_parameters (s);
662 
663   /* insert newly opened handle into list of open handles: */
664   s->next = first_handle;
665   first_handle = s;
666 
667   *handle = s;
668 
669   return SANE_STATUS_GOOD;
670 }
671 
672 void
sane_close(SANE_Handle handle)673 sane_close (SANE_Handle handle)
674 {
675   V4L_Scanner *prev, *s;
676 
677   DBG (2, "sane_close: trying to close handle %p\n", (void *) handle);
678   /* remove handle from list of open handles: */
679   prev = 0;
680   for (s = first_handle; s; s = s->next)
681     {
682       if (s == handle)
683 	break;
684       prev = s;
685     }
686   if (!s)
687     {
688       DBG (1, "sane_close: bad handle %p\n", handle);
689       return;			/* oops, not a handle we know about */
690     }
691   if (prev)
692     prev->next = s->next;
693   else
694     first_handle = s->next;
695 
696   if (s->scanning)
697     sane_cancel (handle);
698   v4l1_close (s->fd);
699   free (s);
700 }
701 
702 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)703 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
704 {
705   V4L_Scanner *s = handle;
706 
707   if ((unsigned) option >= NUM_OPTIONS || option < 0)
708     return 0;
709   DBG (4, "sane_get_option_descriptor: option %d (%s)\n", option,
710        s->opt[option].name ? s->opt[option].name : s->opt[option].title);
711   return s->opt + option;
712 }
713 
714 SANE_Status
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void *val, SANE_Int * info)715 sane_control_option (SANE_Handle handle, SANE_Int option,
716 		     SANE_Action action, void *val, SANE_Int * info)
717 {
718   V4L_Scanner *s = handle;
719   SANE_Status status;
720   SANE_Word cap;
721 
722   if (info)
723     *info = 0;
724 
725   if (option >= NUM_OPTIONS || option < 0)
726     return SANE_STATUS_INVAL;
727 
728   DBG (4, "sane_control_option: %s option %d (%s)\n",
729        action == SANE_ACTION_GET_VALUE ? "get" :
730        action == SANE_ACTION_SET_VALUE ? "set" :
731        action == SANE_ACTION_SET_AUTO ? "auto set" :
732        "(unknown action with)", option,
733        s->opt[option].name ? s->opt[option].name : s->opt[option].title);
734 
735   cap = s->opt[option].cap;
736 
737   if (!SANE_OPTION_IS_ACTIVE (cap))
738     {
739       DBG (1, "sane_control option: option is inactive\n");
740       return SANE_STATUS_INVAL;
741     }
742 
743   if (action == SANE_ACTION_GET_VALUE)
744     {
745       switch (option)
746 	{
747 	  /* word options: */
748 	case OPT_NUM_OPTS:
749 	case OPT_TL_X:
750 	case OPT_TL_Y:
751 	case OPT_BR_X:
752 	case OPT_BR_Y:
753 	case OPT_BRIGHTNESS:
754 	case OPT_HUE:
755 	case OPT_COLOR:
756 	case OPT_CONTRAST:
757 	case OPT_WHITE_LEVEL:
758 	  *(SANE_Word *) val = s->val[option].w;
759 	  return SANE_STATUS_GOOD;
760 	case OPT_CHANNEL:	/* string list options */
761 	case OPT_MODE:
762 	  strcpy (val, s->val[option].s);
763 	  return SANE_STATUS_GOOD;
764 	default:
765 	  DBG (1, "sane_control_option: option %d unknown\n", option);
766 	}
767     }
768   else if (action == SANE_ACTION_SET_VALUE)
769     {
770       if (!SANE_OPTION_IS_SETTABLE (cap))
771 	{
772 	  DBG (1, "sane_control_option: option is not settable\n");
773 	  return SANE_STATUS_INVAL;
774 	}
775       status = sanei_constrain_value (s->opt + option, val, info);
776       if (status != SANE_STATUS_GOOD)
777 	{
778 	  DBG (1, "sane_control_option: sanei_constarin_value failed: %s\n",
779 	       sane_strstatus (status));
780 	  return status;
781 	}
782       if (option >= OPT_TL_X && option <= OPT_BR_Y)
783 	{
784 	  s->user_corner |= 1 << (option - OPT_TL_X);
785 	  if (-1 == v4l1_ioctl (s->fd, VIDIOCGWIN, &s->window))
786 	    {
787 	      DBG (1, "sane_control_option: ioctl VIDIOCGWIN failed "
788 		   "(can not get window geometry)\n");
789 	      return SANE_STATUS_INVAL;
790 	    }
791 	  s->window.clipcount = 0;
792 	  s->window.clips = 0;
793 	  s->window.height = parms.lines;
794 	  s->window.width = parms.pixels_per_line;
795 	}
796 
797 
798       switch (option)
799 	{
800 	  /* (mostly) side-effect-free word options: */
801 	case OPT_TL_X:
802 	  break;
803 	case OPT_TL_Y:
804 	  break;
805 	case OPT_BR_X:
806 	  s->window.width = *(SANE_Word *) val;
807 	  parms.pixels_per_line = *(SANE_Word *) val;
808 	  if (info)
809 	    *info |= SANE_INFO_RELOAD_PARAMS;
810 	  break;
811 	case OPT_BR_Y:
812 	  s->window.height = *(SANE_Word *) val;
813 	  parms.lines = *(SANE_Word *) val;
814 	  if (info)
815 	    *info |= SANE_INFO_RELOAD_PARAMS;
816 	  break;
817 	case OPT_MODE:
818 	  if (info)
819 	    *info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
820 	  s->val[option].s = strdup (val);
821 	  if (!s->val[option].s)
822 	    return SANE_STATUS_NO_MEM;
823 	  if (strcmp (s->val[option].s, SANE_VALUE_SCAN_MODE_GRAY) == 0)
824 	    s->pict.palette = VIDEO_PALETTE_GREY;
825 	  else
826 	    s->pict.palette = VIDEO_PALETTE_RGB24;
827 	  update_parameters (s);
828 	  break;
829 	case OPT_BRIGHTNESS:
830 	  s->pict.brightness = *(SANE_Word *) val *256;
831 	  s->val[option].w = *(SANE_Word *) val;
832 	  break;
833 	case OPT_HUE:
834 	  s->pict.hue = *(SANE_Word *) val *256;
835 	  s->val[option].w = *(SANE_Word *) val;
836 	  break;
837 	case OPT_COLOR:
838 	  s->pict.colour = *(SANE_Word *) val *256;
839 	  s->val[option].w = *(SANE_Word *) val;
840 	  break;
841 	case OPT_CONTRAST:
842 	  s->pict.contrast = *(SANE_Word *) val *256;
843 	  s->val[option].w = *(SANE_Word *) val;
844 	  break;
845 	case OPT_WHITE_LEVEL:
846 	  s->pict.whiteness = *(SANE_Word *) val *256;
847 	  s->val[option].w = *(SANE_Word *) val;
848 	  break;
849 	case OPT_CHANNEL:
850 	  {
851 	    int i;
852 	    struct video_channel channel;
853 
854 	    s->val[option].s = strdup (val);
855 	    if (!s->val[option].s)
856 	      return SANE_STATUS_NO_MEM;
857 	    for (i = 0; i < MAX_CHANNELS; i++)
858 	      {
859 		if (strcmp (s->channel[i], val) == 0)
860 		  {
861 		    channel.channel = i;
862 		    if (-1 == v4l1_ioctl (s->fd, VIDIOCGCHAN, &channel))
863 		      {
864 			DBG (1, "sane_open: can't ioctl VIDIOCGCHAN %s: %s\n",
865 			     s->devicename, strerror (errno));
866 			return SANE_STATUS_INVAL;
867 		      }
868 		    if (-1 == v4l1_ioctl (s->fd, VIDIOCSCHAN, &channel))
869 		      {
870 			DBG (1, "sane_open: can't ioctl VIDIOCSCHAN %s: %s\n",
871 			     s->devicename, strerror (errno));
872 			return SANE_STATUS_INVAL;
873 		      }
874 		    break;
875 		  }
876 	      }
877 	    return SANE_STATUS_GOOD;
878 	    break;
879 	  }
880 	default:
881 	  DBG (1, "sane_control_option: option %d unknown\n", option);
882 	  return SANE_STATUS_INVAL;
883 	}
884       if (option >= OPT_TL_X && option <= OPT_BR_Y)
885 	{
886 	  if (-1 == v4l1_ioctl (s->fd, VIDIOCSWIN, &s->window))
887 	    {
888 	      DBG (1, "sane_control_option: ioctl VIDIOCSWIN failed (%s)\n",
889 		   strerror (errno));
890 	      /* return SANE_STATUS_INVAL; */
891 	    }
892 	  if (-1 == v4l1_ioctl (s->fd, VIDIOCGWIN, &s->window))
893 	    {
894 	      DBG (1, "sane_control_option: ioctl VIDIOCGWIN failed (%s)\n",
895 		   strerror (errno));
896 	      return SANE_STATUS_INVAL;
897 	    }
898 	}
899       if (option >= OPT_BRIGHTNESS && option <= OPT_WHITE_LEVEL)
900 	{
901 	  if (-1 == v4l1_ioctl (s->fd, VIDIOCSPICT, &s->pict))
902 	    {
903 	      DBG (1, "sane_control_option: ioctl VIDIOCSPICT failed (%s)\n",
904 		   strerror (errno));
905 	      /* return SANE_STATUS_INVAL; */
906 	    }
907 	}
908       return SANE_STATUS_GOOD;
909     }
910   else if (action == SANE_ACTION_SET_AUTO)
911     {
912       if (!(cap & SANE_CAP_AUTOMATIC))
913 	{
914 	  DBG (1, "sane_control_option: option can't be set automatically\n");
915 	  return SANE_STATUS_INVAL;
916 	}
917       switch (option)
918 	{
919 	case OPT_BRIGHTNESS:
920 	  /* not implemented yet */
921 	  return SANE_STATUS_GOOD;
922 
923 	default:
924 	  break;
925 	}
926     }
927   return SANE_STATUS_INVAL;
928 }
929 
930 SANE_Status
sane_get_parameters(SANE_Handle handle, SANE_Parameters * params)931 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
932 {
933   V4L_Scanner *s = handle;
934 
935   DBG (4, "sane_get_parameters\n");
936   update_parameters (s);
937   if (params == 0)
938     {
939       DBG (1, "sane_get_parameters: params == 0\n");
940       return SANE_STATUS_INVAL;
941     }
942   if (-1 == v4l1_ioctl (s->fd, VIDIOCGWIN, &s->window))
943     {
944       DBG (1, "sane_control_option: ioctl VIDIOCGWIN failed "
945 	   "(can not get window geometry)\n");
946       return SANE_STATUS_INVAL;
947     }
948   parms.pixels_per_line = s->window.width;
949   parms.bytes_per_line = s->window.width;
950   if (parms.format == SANE_FRAME_RGB)
951     parms.bytes_per_line = s->window.width * 3;
952   parms.lines = s->window.height;
953   *params = parms;
954   return SANE_STATUS_GOOD;
955 
956 }
957 
958 SANE_Status
sane_start(SANE_Handle handle)959 sane_start (SANE_Handle handle)
960 {
961   int len;
962   V4L_Scanner *s;
963   char data;
964 
965   DBG (2, "sane_start\n");
966   for (s = first_handle; s; s = s->next)
967     {
968       if (s == handle)
969 	break;
970     }
971   if (!s)
972     {
973       DBG (1, "sane_start: bad handle %p\n", handle);
974       return SANE_STATUS_INVAL;	/* oops, not a handle we know about */
975     }
976   len = v4l1_ioctl (s->fd, VIDIOCGCAP, &s->capability);
977   if (-1 == len)
978     {
979       DBG (1, "sane_start: can not get capabilities\n");
980       return SANE_STATUS_INVAL;
981     }
982   s->buffercount = 0;
983   if (-1 == v4l1_ioctl (s->fd, VIDIOCGMBUF, &s->mbuf))
984     {
985       s->is_mmap = SANE_FALSE;
986       buffer =
987 	malloc (s->capability.maxwidth * s->capability.maxheight *
988 		s->pict.depth);
989       if (0 == buffer)
990 	return SANE_STATUS_NO_MEM;
991       DBG (3, "sane_start: V4L trying to read frame\n");
992       len = v4l1_read (s->fd, buffer, parms.bytes_per_line * parms.lines);
993       DBG (3, "sane_start: %d bytes read\n", len);
994     }
995   else
996     {
997       int loop;
998       s->is_mmap = SANE_TRUE;
999       DBG (3,
1000 	   "sane_start: mmap frame, buffersize: %d bytes, buffers: %d, offset 0 %d\n",
1001 	   s->mbuf.size, s->mbuf.frames, s->mbuf.offsets[0]);
1002       buffer =
1003 	v4l1_mmap (0, s->mbuf.size, PROT_READ | PROT_WRITE, MAP_SHARED, s->fd, 0);
1004       if (buffer == (void *)-1)
1005 	{
1006 	  DBG (1, "sane_start: mmap failed: %s\n", strerror (errno));
1007 	  buffer = NULL;
1008 	  return SANE_STATUS_IO_ERROR;
1009 	}
1010       DBG (3, "sane_start: mmapped frame, capture 1 pict into %p\n", (void *) buffer);
1011       s->mmap.frame = 0;
1012       s->mmap.width = s->window.width;
1013       /*   s->mmap.width = parms.pixels_per_line;  ??? huh? */
1014       s->mmap.height = s->window.height;
1015       /*      s->mmap.height = parms.lines;  ??? huh? */
1016       s->mmap.format = s->pict.palette;
1017       DBG (2, "sane_start: mmapped frame %d x %d with palette %d\n",
1018 	   s->mmap.width, s->mmap.height, s->mmap.format);
1019 
1020       /* We need to loop here to empty the read buffers, so we don't
1021          get a stale image */
1022       for (loop = 0; loop <= s->mbuf.frames; loop++)
1023         {
1024           len = v4l1_ioctl (s->fd, VIDIOCMCAPTURE, &s->mmap);
1025           if (len == -1)
1026 	    {
1027 	      DBG (1, "sane_start: ioctl VIDIOCMCAPTURE failed: %s\n",
1028 	           strerror (errno));
1029 	      return SANE_STATUS_INVAL;
1030 	    }
1031           DBG (3, "sane_start: waiting for frame %x, loop %d\n", s->mmap.frame, loop);
1032           len = v4l1_ioctl (s->fd, VIDIOCSYNC, &(s->mmap.frame));
1033           if (-1 == len)
1034 	    {
1035 	      DBG (1, "sane_start: call to ioctl(%d, VIDIOCSYNC, ..) failed\n",
1036 	           s->fd);
1037 	      return SANE_STATUS_INVAL;
1038 	    }
1039         }
1040       DBG (3, "sane_start: frame %x done\n", s->mmap.frame);
1041     }
1042 
1043   /* v4l1 actually returns BGR when we ask for RGB, so convert it */
1044   if (s->pict.palette == VIDEO_PALETTE_RGB24)
1045     {
1046       uint32_t loop;
1047       DBG (3, "sane_start: converting from BGR to RGB\n");
1048       for (loop = 0; loop < (s->window.width * s->window.height * 3); loop += 3)
1049         {
1050           data = *(buffer + loop);
1051           *(buffer + loop) = *(buffer + loop + 2);
1052           *(buffer + loop + 2) = data;
1053         }
1054     }
1055 
1056   DBG (3, "sane_start: done\n");
1057   return SANE_STATUS_GOOD;
1058 }
1059 
1060 SANE_Status
sane_read(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * lenp)1061 sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
1062 	   SANE_Int * lenp)
1063 {
1064   int i, min;
1065   V4L_Scanner *s = handle;
1066 
1067   DBG (4, "sane_read: max_len = %d\n", max_len);
1068   if (!lenp)
1069     {
1070       DBG (1, "sane_read: lenp == 0\n");
1071       return SANE_STATUS_INVAL;
1072     }
1073   if ((s->buffercount + 1) > (parms.lines * parms.bytes_per_line))
1074     {
1075       *lenp = 0;
1076       return SANE_STATUS_EOF;
1077     };
1078   min = parms.lines * parms.bytes_per_line;
1079   if (min > (max_len + s->buffercount))
1080     min = (max_len + s->buffercount);
1081   if (s->is_mmap == SANE_FALSE)
1082     {
1083       for (i = s->buffercount; i < (min + 0); i++)
1084 	{
1085 	  *(buf + i - s->buffercount) = *(buffer + i);
1086 	};
1087       *lenp = (parms.lines * parms.bytes_per_line - s->buffercount);
1088       if (max_len < *lenp)
1089 	*lenp = max_len;
1090       DBG (3, "sane_read: transferred %d bytes (from %d to %d)\n", *lenp,
1091 	   s->buffercount, i);
1092       s->buffercount = i;
1093     }
1094   else
1095     {
1096       for (i = s->buffercount; i < (min + 0); i++)
1097 	{
1098 	  *(buf + i - s->buffercount) = *(buffer + i);
1099 	};
1100       *lenp = (parms.lines * parms.bytes_per_line - s->buffercount);
1101       if ((i - s->buffercount) < *lenp)
1102 	*lenp = (i - s->buffercount);
1103       DBG (3, "sane_read: transferred %d bytes (from %d to %d)\n", *lenp,
1104 	   s->buffercount, i);
1105       s->buffercount = i;
1106     }
1107   return SANE_STATUS_GOOD;
1108 }
1109 
1110 void
sane_cancel(SANE_Handle handle)1111 sane_cancel (SANE_Handle handle)
1112 {
1113   V4L_Scanner *s = handle;
1114 
1115   DBG (2, "sane_cancel\n");
1116 
1117   /* ??? buffer isn't checked in sane_read? */
1118   if (buffer)
1119     {
1120       if (s->is_mmap)
1121 	v4l1_munmap(buffer, s->mbuf.size);
1122       else
1123 	free (buffer);
1124 
1125       buffer = NULL;
1126     }
1127 }
1128 
1129 
1130 SANE_Status
sane_set_io_mode(SANE_Handle __sane_unused__ handle, SANE_Bool non_blocking)1131 sane_set_io_mode (SANE_Handle __sane_unused__ handle, SANE_Bool non_blocking)
1132 {
1133   if (non_blocking == SANE_FALSE)
1134     return SANE_STATUS_GOOD;
1135   return SANE_STATUS_UNSUPPORTED;
1136 }
1137 
1138 SANE_Status
sane_get_select_fd(SANE_Handle __sane_unused__ handle, SANE_Int __sane_unused__ * fd)1139 sane_get_select_fd (SANE_Handle __sane_unused__ handle, SANE_Int __sane_unused__ * fd)
1140 {
1141   return SANE_STATUS_UNSUPPORTED;
1142 }
1143