1 /* Simple Video4Linux image grabber. */
3 * Video4Linux Driver Test/Example Framegrabbing Program
6 * gcc -s -Wall -Wstrict-prototypes v4lgrab.c -o v4lgrab
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).
15 * For some cameras you may need to pre-load libv4l to perform
16 * the necessary decompression, e.g.:
18 * export LD_PRELOAD=/usr/lib/libv4l/v4l1compat.so
19 * ./v4lgrab >image.ppm
21 * see http://hansdegoede.livejournal.com/3636.html for details.
26 #include <sys/types.h>
30 #include <sys/ioctl.h>
33 #include <linux/types.h>
34 #include <linux/videodev.h>
36 #define VIDEO_DEV "/dev/video0"
38 /* Stole this from tvset.c */
40 #define READ_VIDEO_PIXEL(buf, format, depth, r, g, b) \
44 case VIDEO_PALETTE_GREY: \
50 (r) = (g) = (b) = (*buf++ << 8);\
55 *((unsigned short *) buf); \
62 case VIDEO_PALETTE_RGB565: \
64 unsigned short tmp = *(unsigned short *)buf; \
66 (g) = (tmp<<5)&0xFC00; \
67 (b) = (tmp<<11)&0xF800; \
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; \
79 case VIDEO_PALETTE_RGB24: \
80 (r) = buf[0] << 8; (g) = buf[1] << 8; \
87 "Format %d not yet supported\n", \
92 int get_brightness_adj(unsigned char *image
, long size
, int *brightness
) {
94 for (i
=0;i
<size
*3;i
++)
96 *brightness
= (128 - tot
/(size
*3))/3;
97 return !((tot
/(size
*3)) >= 126 && (tot
/(size
*3)) <= 130);
100 int main(int argc
, char ** argv
)
102 int fd
= open(VIDEO_DEV
, O_RDONLY
), f
;
103 struct video_capability cap
;
104 struct video_window win
;
105 struct video_picture vpic
;
107 unsigned char *buffer
, *src
;
108 int bpp
= 24, r
= 0, g
= 0, b
= 0;
109 unsigned int i
, src_depth
= 16;
116 if (ioctl(fd
, VIDIOCGCAP
, &cap
) < 0) {
118 fprintf(stderr
, "(" VIDEO_DEV
" not a video4linux device?)\n");
123 if (ioctl(fd
, VIDIOCGWIN
, &win
) < 0) {
124 perror("VIDIOCGWIN");
129 if (ioctl(fd
, VIDIOCGPICT
, &vpic
) < 0) {
130 perror("VIDIOCGPICT");
135 if (cap
.type
& VID_TYPE_MONOCHROME
) {
137 vpic
.palette
=VIDEO_PALETTE_GREY
; /* 8bit grey */
138 if(ioctl(fd
, VIDIOCSPICT
, &vpic
) < 0) {
140 if(ioctl(fd
, VIDIOCSPICT
, &vpic
) < 0) {
142 if(ioctl(fd
, VIDIOCSPICT
, &vpic
) < 0) {
143 fprintf(stderr
, "Unable to find a supported capture format.\n");
151 vpic
.palette
=VIDEO_PALETTE_RGB24
;
153 if(ioctl(fd
, VIDIOCSPICT
, &vpic
) < 0) {
154 vpic
.palette
=VIDEO_PALETTE_RGB565
;
157 if(ioctl(fd
, VIDIOCSPICT
, &vpic
)==-1) {
158 vpic
.palette
=VIDEO_PALETTE_RGB555
;
161 if(ioctl(fd
, VIDIOCSPICT
, &vpic
)==-1) {
162 fprintf(stderr
, "Unable to find a supported capture format.\n");
169 buffer
= malloc(win
.width
* win
.height
* bpp
);
171 fprintf(stderr
, "Out of memory.\n");
177 read(fd
, buffer
, win
.width
* win
.height
* bpp
);
178 f
= get_brightness_adj(buffer
, win
.width
* win
.height
, &newbright
);
180 vpic
.brightness
+= (newbright
<< 8);
181 if(ioctl(fd
, VIDIOCSPICT
, &vpic
)==-1) {
182 perror("VIDIOSPICT");
188 fprintf(stdout
, "P6\n%d %d 255\n", win
.width
, win
.height
);
192 for (i
= 0; i
< win
.width
* win
.height
; i
++) {
193 READ_VIDEO_PIXEL(src
, vpic
.palette
, src_depth
, r
, g
, b
);