linux/Documentation/video4linux/v4lgrab.c
<<
>>
Prefs
   1/* Simple Video4Linux image grabber. */
   2/*
   3 *      Video4Linux Driver Test/Example Framegrabbing Program
   4 *
   5 *      Compile with:
   6 *              gcc -s -Wall -Wstrict-prototypes v4lgrab.c -o v4lgrab
   7 *      Use as:
   8 *              v4lgrab >image.ppm
   9 *
  10 *      Copyright (C) 1998-05-03, Phil Blundell <philb@gnu.org>
  11 *      Copied from http://www.tazenda.demon.co.uk/phil/vgrabber.c
  12 *      with minor modifications (Dave Forrest, drf5n@virginia.edu).
  13 *
  14 *
  15 *      For some cameras you may need to pre-load libv4l to perform
  16 *      the necessary decompression, e.g.:
  17 *
  18 *      export LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so
  19 *      ./v4lgrab >image.ppm
  20 *
  21 *      see http://hansdegoede.livejournal.com/3636.html for details.
  22 *
  23 */
  24
  25#include <unistd.h>
  26#include <sys/types.h>
  27#include <sys/stat.h>
  28#include <fcntl.h>
  29#include <stdio.h>
  30#include <sys/ioctl.h>
  31#include <stdlib.h>
  32
  33#include <linux/types.h>
  34#include <linux/videodev.h>
  35
  36#define VIDEO_DEV "/dev/video0"
  37
  38/* Stole this from tvset.c */
  39
  40#define READ_VIDEO_PIXEL(buf, format, depth, r, g, b)                   \
  41{                                                                       \
  42        switch (format)                                                 \
  43        {                                                               \
  44                case VIDEO_PALETTE_GREY:                                \
  45                        switch (depth)                                  \
  46                        {                                               \
  47                                case 4:                                 \
  48                                case 6:                                 \
  49                                case 8:                                 \
  50                                        (r) = (g) = (b) = (*buf++ << 8);\
  51                                        break;                          \
  52                                                                        \
  53                                case 16:                                \
  54                                        (r) = (g) = (b) =               \
  55                                                *((unsigned short *) buf);      \
  56                                        buf += 2;                       \
  57                                        break;                          \
  58                        }                                               \
  59                        break;                                          \
  60                                                                        \
  61                                                                        \
  62                case VIDEO_PALETTE_RGB565:                              \
  63                {                                                       \
  64                        unsigned short tmp = *(unsigned short *)buf;    \
  65                        (r) = tmp&0xF800;                               \
  66                        (g) = (tmp<<5)&0xFC00;                          \
  67                        (b) = (tmp<<11)&0xF800;                         \
  68                        buf += 2;                                       \
  69                }                                                       \
  70                break;                                                  \
  71                                                                        \
  72                case VIDEO_PALETTE_RGB555:                              \
  73                        (r) = (buf[0]&0xF8)<<8;                         \
  74                        (g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8;    \
  75                        (b) = ((buf[1] << 2 ) & 0xF8)<<8;               \
  76                        buf += 2;                                       \
  77                        break;                                          \
  78                                                                        \
  79                case VIDEO_PALETTE_RGB24:                               \
  80                        (r) = buf[0] << 8; (g) = buf[1] << 8;           \
  81                        (b) = buf[2] << 8;                              \
  82                        buf += 3;                                       \
  83                        break;                                          \
  84                                                                        \
  85                default:                                                \
  86                        fprintf(stderr,                                 \
  87                                "Format %d not yet supported\n",        \
  88                                format);                                \
  89        }                                                               \
  90}
  91
  92static int get_brightness_adj(unsigned char *image, long size, int *brightness) {
  93  long i, tot = 0;
  94  for (i=0;i<size*3;i++)
  95    tot += image[i];
  96  *brightness = (128 - tot/(size*3))/3;
  97  return !((tot/(size*3)) >= 126 && (tot/(size*3)) <= 130);
  98}
  99
 100int main(int argc, char ** argv)
 101{
 102  int fd = open(VIDEO_DEV, O_RDONLY), f;
 103  struct video_capability cap;
 104  struct video_window win;
 105  struct video_picture vpic;
 106
 107  unsigned char *buffer, *src;
 108  int bpp = 24, r = 0, g = 0, b = 0;
 109  unsigned int i, src_depth = 16;
 110
 111  if (fd < 0) {
 112    perror(VIDEO_DEV);
 113    exit(1);
 114  }
 115
 116  if (ioctl(fd, VIDIOCGCAP, &cap) < 0) {
 117    perror("VIDIOGCAP");
 118    fprintf(stderr, "(" VIDEO_DEV " not a video4linux device?)\n");
 119    close(fd);
 120    exit(1);
 121  }
 122
 123  if (ioctl(fd, VIDIOCGWIN, &win) < 0) {
 124    perror("VIDIOCGWIN");
 125    close(fd);
 126    exit(1);
 127  }
 128
 129  if (ioctl(fd, VIDIOCGPICT, &vpic) < 0) {
 130    perror("VIDIOCGPICT");
 131    close(fd);
 132    exit(1);
 133  }
 134
 135  if (cap.type & VID_TYPE_MONOCHROME) {
 136    vpic.depth=8;
 137    vpic.palette=VIDEO_PALETTE_GREY;    /* 8bit grey */
 138    if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
 139      vpic.depth=6;
 140      if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
 141        vpic.depth=4;
 142        if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
 143          fprintf(stderr, "Unable to find a supported capture format.\n");
 144          close(fd);
 145          exit(1);
 146        }
 147      }
 148    }
 149  } else {
 150    vpic.depth=24;
 151    vpic.palette=VIDEO_PALETTE_RGB24;
 152
 153    if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {
 154      vpic.palette=VIDEO_PALETTE_RGB565;
 155      vpic.depth=16;
 156
 157      if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
 158        vpic.palette=VIDEO_PALETTE_RGB555;
 159        vpic.depth=15;
 160
 161        if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
 162          fprintf(stderr, "Unable to find a supported capture format.\n");
 163          return -1;
 164        }
 165      }
 166    }
 167  }
 168
 169  buffer = malloc(win.width * win.height * bpp);
 170  if (!buffer) {
 171    fprintf(stderr, "Out of memory.\n");
 172    exit(1);
 173  }
 174
 175  do {
 176    int newbright;
 177    read(fd, buffer, win.width * win.height * bpp);
 178    f = get_brightness_adj(buffer, win.width * win.height, &newbright);
 179    if (f) {
 180      vpic.brightness += (newbright << 8);
 181      if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) {
 182        perror("VIDIOSPICT");
 183        break;
 184      }
 185    }
 186  } while (f);
 187
 188  fprintf(stdout, "P6\n%d %d 255\n", win.width, win.height);
 189
 190  src = buffer;
 191
 192  for (i = 0; i < win.width * win.height; i++) {
 193    READ_VIDEO_PIXEL(src, vpic.palette, src_depth, r, g, b);
 194    fputc(r>>8, stdout);
 195    fputc(g>>8, stdout);
 196    fputc(b>>8, stdout);
 197  }
 198
 199  close(fd);
 200  return 0;
 201}
 202
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.