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 16#include <unistd.h> 17#include <sys/types.h> 18#include <sys/stat.h> 19#include <fcntl.h> 20#include <stdio.h> 21#include <sys/ioctl.h> 22#include <stdlib.h> 23 24#include <linux/types.h> 25#include <linux/videodev.h> 26 27#define FILE "/dev/video0" 28 29/* Stole this from tvset.c */ 30 31#define READ_VIDEO_PIXEL(buf, format, depth, r, g, b) \ 32{ \ 33 switch (format) \ 34 { \ 35 case VIDEO_PALETTE_GREY: \ 36 switch (depth) \ 37 { \ 38 case 4: \ 39 case 6: \ 40 case 8: \ 41 (r) = (g) = (b) = (*buf++ << 8);\ 42 break; \ 43 \ 44 case 16: \ 45 (r) = (g) = (b) = \ 46 *((unsigned short *) buf); \ 47 buf += 2; \ 48 break; \ 49 } \ 50 break; \ 51 \ 52 \ 53 case VIDEO_PALETTE_RGB565: \ 54 { \ 55 unsigned short tmp = *(unsigned short *)buf; \ 56 (r) = tmp&0xF800; \ 57 (g) = (tmp<<5)&0xFC00; \ 58 (b) = (tmp<<11)&0xF800; \ 59 buf += 2; \ 60 } \ 61 break; \ 62 \ 63 case VIDEO_PALETTE_RGB555: \ 64 (r) = (buf[0]&0xF8)<<8; \ 65 (g) = ((buf[0] << 5 | buf[1] >> 3)&0xF8)<<8; \ 66 (b) = ((buf[1] << 2 ) & 0xF8)<<8; \ 67 buf += 2; \ 68 break; \ 69 \ 70 case VIDEO_PALETTE_RGB24: \ 71 (r) = buf[0] << 8; (g) = buf[1] << 8; \ 72 (b) = buf[2] << 8; \ 73 buf += 3; \ 74 break; \ 75 \ 76 default: \ 77 fprintf(stderr, \ 78 "Format %d not yet supported\n", \ 79 format); \ 80 } \ 81} 82 83int get_brightness_adj(unsigned char *image, long size, int *brightness) { 84 long i, tot = 0; 85 for (i=0;i<size*3;i++) 86 tot += image[i]; 87 *brightness = (128 - tot/(size*3))/3; 88 return !((tot/(size*3)) >= 126 && (tot/(size*3)) <= 130); 89} 90 91int main(int argc, char ** argv) 92{ 93 int fd = open(FILE, O_RDONLY), f; 94 struct video_capability cap; 95 struct video_window win; 96 struct video_picture vpic; 97 98 unsigned char *buffer, *src; 99 int bpp = 24, r, g, b; 100 unsigned int i, src_depth; 101 102 if (fd < 0) { 103 perror(FILE); 104 exit(1); 105 } 106 107 if (ioctl(fd, VIDIOCGCAP, &cap) < 0) { 108 perror("VIDIOGCAP"); 109 fprintf(stderr, "(" FILE " not a video4linux device?)\n"); 110 close(fd); 111 exit(1); 112 } 113 114 if (ioctl(fd, VIDIOCGWIN, &win) < 0) { 115 perror("VIDIOCGWIN"); 116 close(fd); 117 exit(1); 118 } 119 120 if (ioctl(fd, VIDIOCGPICT, &vpic) < 0) { 121 perror("VIDIOCGPICT"); 122 close(fd); 123 exit(1); 124 } 125 126 if (cap.type & VID_TYPE_MONOCHROME) { 127 vpic.depth=8; 128 vpic.palette=VIDEO_PALETTE_GREY; /* 8bit grey */ 129 if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { 130 vpic.depth=6; 131 if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { 132 vpic.depth=4; 133 if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { 134 fprintf(stderr, "Unable to find a supported capture format.\n"); 135 close(fd); 136 exit(1); 137 } 138 } 139 } 140 } else { 141 vpic.depth=24; 142 vpic.palette=VIDEO_PALETTE_RGB24; 143 144 if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) { 145 vpic.palette=VIDEO_PALETTE_RGB565; 146 vpic.depth=16; 147 148 if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { 149 vpic.palette=VIDEO_PALETTE_RGB555; 150 vpic.depth=15; 151 152 if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { 153 fprintf(stderr, "Unable to find a supported capture format.\n"); 154 return -1; 155 } 156 } 157 } 158 } 159 160 buffer = malloc(win.width * win.height * bpp); 161 if (!buffer) { 162 fprintf(stderr, "Out of memory.\n"); 163 exit(1); 164 } 165 166 do { 167 int newbright; 168 read(fd, buffer, win.width * win.height * bpp); 169 f = get_brightness_adj(buffer, win.width * win.height, &newbright); 170 if (f) { 171 vpic.brightness += (newbright << 8); 172 if(ioctl(fd, VIDIOCSPICT, &vpic)==-1) { 173 perror("VIDIOSPICT"); 174 break; 175 } 176 } 177 } while (f); 178 179 fprintf(stdout, "P6\n%d %d 255\n", win.width, win.height); 180 181 src = buffer; 182 183 for (i = 0; i < win.width * win.height; i++) { 184 READ_VIDEO_PIXEL(src, vpic.palette, src_depth, r, g, b); 185 fputc(r>>8, stdout); 186 fputc(g>>8, stdout); 187 fputc(b>>8, stdout); 188 } 189 190 close(fd); 191 return 0; 192} 193