camcapture 0.1.0-i686-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README ADDED
@@ -0,0 +1,21 @@
1
+ -----Ruby/CamCapture-----
2
+
3
+ -- Description --
4
+
5
+ Ruby/CamCapture is a Ruby library that provides a class for grabbing
6
+ images from a camera, through the video4linux interface.
7
+
8
+ This library is compatible with Ruby Threads, which means that it can be used
9
+ in combination with TCPServer, sockets, serial port communication (Ruby/Serialport), etc.
10
+
11
+ -- Installation --
12
+
13
+ $ cd ext
14
+ $ ruby extconf.rb
15
+ $ make
16
+ $ sudo make install
17
+
18
+ -- Testing --
19
+
20
+ * test/test.rb
21
+
data/ext/extconf.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+ create_makefile('camcapture')
3
+
@@ -0,0 +1,253 @@
1
+ /* CamCapture Ruby class :
2
+ * Video4Linux video capture
3
+ * compatible with Ruby Threads
4
+ *
5
+ * Copyright 2006 Bruno STEUX / Ecole des Mines de Paris
6
+ *
7
+ * Released under Ruby License
8
+ */
9
+
10
+ #include <ruby.h> /* ruby inclusion */
11
+ #include <rubyio.h> /* ruby io inclusion */
12
+
13
+ static VALUE cCamCapture; /* camera capture class */
14
+
15
+ #include <stdlib.h>
16
+ #include <stdio.h>
17
+ #include <string.h>
18
+ #include <fcntl.h>
19
+ #include <unistd.h>
20
+ #include <errno.h> /* Error number definitions */
21
+ #include <sys/types.h>
22
+ #include <sys/stat.h>
23
+ #include <sys/ioctl.h>
24
+ #include <sys/mman.h>
25
+ #include <linux/videodev.h>
26
+
27
+ static int cam_capture_get_fd(VALUE obj)
28
+ {
29
+ OpenFile *fptr;
30
+
31
+ GetOpenFile(obj, fptr);
32
+ return (fileno(fptr->f));
33
+ }
34
+
35
+ static void put32(unsigned long value, FILE* outf)
36
+ {
37
+ fputc(value & 0xff,outf);
38
+ fputc((value >> 8) & 0xff,outf);
39
+ fputc((value >> 16) & 0xff,outf);
40
+ fputc((value >> 24) & 0xff,outf);
41
+ }
42
+
43
+ static void put16(unsigned int value, FILE* outf)
44
+ {
45
+ fputc(value & 0xff,outf);
46
+ fputc((value >> 8) & 0xff,outf);
47
+ }
48
+
49
+ static VALUE cam_capture_save_bmp(VALUE self, VALUE filename)
50
+ {
51
+ VALUE image,image2;
52
+ char *imageData=RSTRING(image)->ptr;
53
+ char *fnx=RSTRING(filename)->ptr;
54
+ int width,height;
55
+ int h,w,r,g,b;
56
+ FILE *outfile;
57
+ VALUE rwidth, rheight;
58
+
59
+ rwidth=rb_iv_get(self, "@width");
60
+ width=NUM2INT(rwidth);
61
+ rheight=rb_iv_get(self, "@height");
62
+ height=NUM2INT(rheight);
63
+ image=rb_iv_get(self, "@image");
64
+ image2=StringValue(image);
65
+ if (RSTRING(image2)->len != width*height*3) {
66
+ rb_raise(rb_eRuntimeError, "image is not correct");
67
+ }
68
+ imageData=RSTRING(image2)->ptr;
69
+
70
+ outfile = fopen(fnx, "wb");
71
+ if (outfile == NULL)
72
+ {
73
+ printf("Can't open output file.\n");
74
+ exit(0);
75
+ }
76
+
77
+ fputc('B',outfile);
78
+ fputc('M',outfile);
79
+ put32(54+width*height*3, outfile);
80
+ put32(0L, outfile);
81
+ put32(54, outfile);
82
+
83
+ put32(40L, outfile);
84
+ put32(width, outfile);
85
+ put32(height, outfile);
86
+ put16(1, outfile);
87
+ put16(24, outfile);
88
+ put32(0, outfile);
89
+ put32(width*height*3, outfile);
90
+ put32(10000, outfile);
91
+ put32(10000, outfile);
92
+ put32(0, outfile);
93
+ put32(0, outfile);
94
+
95
+ for (h=height-1; h>=0; h--)
96
+ {
97
+ for (w=0; w<width; w++)
98
+ {
99
+ b = (int)*(imageData+w*3+h*width*3);
100
+ g = (int)*(imageData+w*3+h*width*3+1);
101
+ r = (int)*(imageData+w*3+h*width*3+2);
102
+
103
+ putc(b,outfile); /* B */
104
+ putc(g,outfile); /* G */
105
+ putc(r,outfile); /* R */
106
+ }
107
+ }
108
+ fclose (outfile);
109
+ return Qnil;
110
+ }
111
+
112
+ static VALUE cam_capture_create(VALUE class, VALUE device_number, VALUE width, VALUE height, VALUE palette)
113
+ {
114
+ OpenFile *fp;
115
+ int fd;
116
+ char sdevice[]="/dev/videoX";
117
+
118
+ struct video_capability vid_cap;
119
+ struct video_window vid_win;
120
+ struct video_channel vid_chan;
121
+ struct video_picture vid_pic;
122
+
123
+ sdevice[strlen(sdevice)-1]='0'+NUM2INT(device_number);
124
+
125
+ NEWOBJ(capture, struct RFile);
126
+ rb_secure(4);
127
+ OBJSETUP(capture, class, T_FILE);
128
+ MakeOpenFile(capture, fp);
129
+
130
+ fd = open(sdevice, O_RDWR | O_NONBLOCK);
131
+ if (fd == -1)
132
+ rb_sys_fail(sdevice);
133
+
134
+ // Enable blocking read
135
+ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
136
+
137
+ fp->f = rb_fdopen(fd, "r+");
138
+ fp->mode = FMODE_READWRITE | FMODE_SYNC;
139
+
140
+ if (ioctl(fd, VIDIOCGCAP, &vid_cap) == -1) {
141
+ rb_raise(rb_eIOError, "CamCapture : VIDIOCGCAP");
142
+ return Qnil;
143
+ }
144
+
145
+ if (!(vid_cap.type & VID_TYPE_CAPTURE)) {
146
+ char s[256];
147
+ sprintf(s,"%s is not a video capture device",sdevice);
148
+ rb_raise(rb_eIOError, s);
149
+ return Qnil;
150
+ }
151
+
152
+ if (ioctl(fd, VIDIOCGWIN, &vid_win) == -1) {
153
+ rb_raise(rb_eIOError, "CamCapture : VIDIOCGWIN");
154
+ return Qnil;
155
+ }
156
+
157
+ if (NUM2INT(width)!=0) {
158
+ vid_win.width=NUM2INT(width);
159
+ }
160
+ if (NUM2INT(height)!=0) {
161
+ vid_win.height=NUM2INT(height);
162
+ }
163
+ if (ioctl(fd, VIDIOCSWIN, &vid_win) == -1) {
164
+ rb_raise(rb_eIOError, "CamCapture : VIDIOCSWIN");
165
+ return Qnil;
166
+ }
167
+
168
+ rb_iv_set((VALUE)capture,"@width",INT2FIX(vid_win.width));
169
+ rb_iv_set((VALUE)capture,"@height",INT2FIX(vid_win.height));
170
+ rb_iv_set((VALUE)capture,"@image",rb_str_new2(""));
171
+
172
+ if (ioctl(fd, VIDIOCGCHAN, &(vid_chan)) == -1) {
173
+ rb_raise(rb_eIOError, "CamCapture : VIDIOCGCHAN");
174
+ return Qnil;
175
+ }
176
+ vid_chan.channel = 0;
177
+ vid_chan.norm = VIDEO_MODE_NTSC;
178
+ if (ioctl(fd, VIDIOCSCHAN, &(vid_chan)) == -1) {
179
+ rb_raise(rb_eIOError, "CamCapture : VIDIOCSCHAN");
180
+ return Qnil;
181
+ }
182
+
183
+ if (ioctl(fd, VIDIOCGPICT, &(vid_pic)) == -1) {
184
+ rb_raise(rb_eIOError, "CamCapture : VIDIOCGPICT");
185
+ return Qnil;
186
+ }
187
+ vid_pic.palette = VIDEO_PALETTE_RGB24;
188
+ if (NUM2INT(palette)!=0) {
189
+ vid_pic.palette=NUM2INT(palette);
190
+ }
191
+ if (ioctl(fd, VIDIOCSPICT, &(vid_pic)) == -1) {
192
+ rb_raise(rb_eIOError, "CamCapture : VIDIOCSPICT");
193
+ return Qnil;
194
+ }
195
+
196
+ return (VALUE) capture;
197
+ }
198
+
199
+ void Init_camcapture() {
200
+ cCamCapture = rb_define_class("CamCapture", rb_cIO);
201
+ rb_define_singleton_method(cCamCapture, "create", cam_capture_create, 4);
202
+ rb_define_method(cCamCapture, "save_bmp", cam_capture_save_bmp, 1);
203
+
204
+ #define VIDEO_PALETTE_GREY 1 /* Linear greyscale */
205
+ #define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */
206
+ #define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */
207
+ #define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */
208
+ #define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */
209
+ #define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */
210
+ #define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */
211
+ #define VIDEO_PALETTE_YUYV 8
212
+ #define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */
213
+ #define VIDEO_PALETTE_YUV420 10
214
+ #define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */
215
+ #define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */
216
+ #define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */
217
+ #define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */
218
+ #define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */
219
+ #define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */
220
+
221
+ rb_define_const(cCamCapture, "GREY", INT2FIX(VIDEO_PALETTE_GREY));
222
+ rb_define_const(cCamCapture, "RGB24", INT2FIX(VIDEO_PALETTE_RGB24));
223
+ rb_define_const(cCamCapture, "RGB32", INT2FIX(VIDEO_PALETTE_RGB32));
224
+ rb_define_const(cCamCapture, "YUV422", INT2FIX(VIDEO_PALETTE_YUV422));
225
+
226
+ /* The following definitions are more easily carried out in Ruby */
227
+ rb_eval_string(
228
+ "class CamCapture\n"
229
+
230
+ "attr_reader :width, :height, :image\n"
231
+
232
+ "def CamCapture.new(device_number=0, w=0, h=0, palette=0)\n"
233
+ "cap = create(device_number, w, h, palette)\n"
234
+ "return cap\n"
235
+ "end\n"
236
+
237
+ "def capture\n"
238
+ "sysread(@width*@height*3,@image)\n"
239
+ "end\n"
240
+
241
+ "end\n"
242
+ );
243
+ }
244
+
245
+ /* For CamelliaLib interfacing :
246
+ *
247
+ "def capture(image)\n"
248
+ "image.alloc_bgr(@width, @height) if image.width != @width or image.height != @height or not image.allocated?\n"
249
+ "if image.widthStep != @width*3 then image=nil; return; end\n"
250
+ "image.set_pixels(sysread(@width*@height*3,@image))\n"
251
+ "end\n"
252
+ */
253
+
data/lib/camcapture.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'camcapture.so'
2
+
3
+ class CamCapture
4
+ attr_reader :width, :height, :image
5
+
6
+ def CamCapture.new(device_number=0, w=0, h=0, palette=0)
7
+ cap = create(device_number, w, h, palette)
8
+ return cap
9
+ end
10
+
11
+ def capture
12
+ sysread(@width*@height*3,@image)
13
+ end
14
+ end
15
+
16
+
data/test/test.rb ADDED
@@ -0,0 +1,14 @@
1
+ begin
2
+ require 'camcapture'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require_gem 'camcapture'
6
+ end
7
+
8
+ camera=CamCapture.new 0, 320, 240
9
+ puts "Image size is #{camera.width}x#{camera.height}"
10
+ for i in 1..10 do
11
+ image=camera.capture
12
+ puts "image #{i} : #{image.length} bytes grabbed"
13
+ camera.save_bmp("grab#{i}.bmp")
14
+ end
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: camcapture
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.0
7
+ date: 2006-10-06 00:00:00 +02:00
8
+ summary: Camera/Webcam capture using Video4Linux interface. Compatible with Ruby Threads.
9
+ require_paths:
10
+ - lib
11
+ email: bruno.steux@ensmp.fr
12
+ homepage: http://camellia.rubyforge.org
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: camcapture
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: i686-linux
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Bruno STEUX
31
+ files:
32
+ - ext/ruby_camcapture.c
33
+ - ext/extconf.rb
34
+ - lib/camcapture.rb
35
+ - README
36
+ test_files:
37
+ - test/test.rb
38
+ rdoc_options: []
39
+
40
+ extra_rdoc_files:
41
+ - README
42
+ executables: []
43
+
44
+ extensions:
45
+ - ext/extconf.rb
46
+ requirements: []
47
+
48
+ dependencies: []
49
+