blob: 079b628481cf6a566a47b071ba354b6d3d0a1910 [file] [log] [blame]
Randy Dunlapa22f1cb2006-05-26 10:32:13 -03001/* 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}