rays 0.1.11 → 0.1.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. checksums.yaml +5 -5
  2. data/.doc/ext/rays/bitmap.cpp +22 -76
  3. data/.doc/ext/rays/bounds.cpp +95 -125
  4. data/.doc/ext/rays/camera.cpp +88 -0
  5. data/.doc/ext/rays/color.cpp +223 -45
  6. data/.doc/ext/rays/color_space.cpp +146 -46
  7. data/.doc/ext/rays/defs.cpp +183 -0
  8. data/.doc/ext/rays/font.cpp +69 -21
  9. data/.doc/ext/rays/image.cpp +26 -37
  10. data/.doc/ext/rays/matrix.cpp +186 -29
  11. data/.doc/ext/rays/native.cpp +14 -8
  12. data/.doc/ext/rays/noise.cpp +53 -0
  13. data/.doc/ext/rays/painter.cpp +187 -292
  14. data/.doc/ext/rays/point.cpp +96 -77
  15. data/.doc/ext/rays/polygon.cpp +313 -0
  16. data/.doc/ext/rays/polygon_line.cpp +96 -0
  17. data/.doc/ext/rays/polyline.cpp +167 -0
  18. data/.doc/ext/rays/rays.cpp +103 -12
  19. data/.doc/ext/rays/shader.cpp +83 -9
  20. data/LICENSE +21 -0
  21. data/README.md +1 -1
  22. data/Rakefile +24 -9
  23. data/VERSION +1 -1
  24. data/ext/rays/bitmap.cpp +22 -80
  25. data/ext/rays/bounds.cpp +100 -128
  26. data/ext/rays/camera.cpp +94 -0
  27. data/ext/rays/color.cpp +231 -51
  28. data/ext/rays/color_space.cpp +149 -47
  29. data/ext/rays/defs.cpp +183 -0
  30. data/ext/rays/defs.h +26 -2
  31. data/ext/rays/extconf.rb +2 -3
  32. data/ext/rays/font.cpp +74 -24
  33. data/ext/rays/image.cpp +28 -40
  34. data/ext/rays/matrix.cpp +198 -30
  35. data/ext/rays/native.cpp +14 -8
  36. data/ext/rays/noise.cpp +55 -0
  37. data/ext/rays/painter.cpp +203 -298
  38. data/ext/rays/point.cpp +105 -81
  39. data/ext/rays/polygon.cpp +329 -0
  40. data/ext/rays/polygon_line.cpp +99 -0
  41. data/ext/rays/polyline.cpp +176 -0
  42. data/ext/rays/rays.cpp +103 -13
  43. data/ext/rays/shader.cpp +84 -9
  44. data/include/rays.h +10 -2
  45. data/include/rays/bitmap.h +14 -26
  46. data/include/rays/bounds.h +21 -4
  47. data/include/rays/camera.h +49 -0
  48. data/include/rays/color.h +25 -14
  49. data/include/rays/color_space.h +15 -10
  50. data/include/rays/coord.h +114 -0
  51. data/include/rays/debug.h +22 -0
  52. data/include/rays/defs.h +36 -0
  53. data/include/rays/exception.h +6 -2
  54. data/include/rays/font.h +4 -4
  55. data/include/rays/image.h +12 -18
  56. data/include/rays/matrix.h +50 -24
  57. data/include/rays/noise.h +42 -0
  58. data/include/rays/opengl.h +2 -50
  59. data/include/rays/painter.h +89 -93
  60. data/include/rays/point.h +44 -51
  61. data/include/rays/polygon.h +198 -0
  62. data/include/rays/polyline.h +71 -0
  63. data/include/rays/rays.h +3 -0
  64. data/include/rays/ruby.h +7 -1
  65. data/include/rays/ruby/bounds.h +1 -1
  66. data/include/rays/ruby/camera.h +41 -0
  67. data/include/rays/ruby/color.h +1 -1
  68. data/include/rays/ruby/color_space.h +1 -1
  69. data/include/rays/ruby/font.h +1 -1
  70. data/include/rays/ruby/matrix.h +1 -1
  71. data/include/rays/ruby/point.h +1 -1
  72. data/include/rays/ruby/polygon.h +52 -0
  73. data/include/rays/ruby/polyline.h +41 -0
  74. data/include/rays/ruby/rays.h +8 -0
  75. data/include/rays/ruby/shader.h +1 -1
  76. data/include/rays/shader.h +36 -8
  77. data/lib/rays.rb +7 -2
  78. data/lib/rays/bitmap.rb +0 -15
  79. data/lib/rays/bounds.rb +17 -23
  80. data/lib/rays/camera.rb +21 -0
  81. data/lib/rays/color.rb +20 -47
  82. data/lib/rays/color_space.rb +13 -13
  83. data/lib/rays/image.rb +3 -7
  84. data/lib/rays/matrix.rb +28 -0
  85. data/lib/rays/module.rb +4 -19
  86. data/lib/rays/painter.rb +78 -93
  87. data/lib/rays/point.rb +13 -21
  88. data/lib/rays/polygon.rb +58 -0
  89. data/lib/rays/polygon_line.rb +36 -0
  90. data/lib/rays/polyline.rb +32 -0
  91. data/lib/rays/shader.rb +20 -1
  92. data/rays.gemspec +5 -7
  93. data/src/bitmap.h +36 -0
  94. data/src/bounds.cpp +74 -11
  95. data/src/color.cpp +58 -23
  96. data/src/color_space.cpp +52 -34
  97. data/src/color_space.h +22 -0
  98. data/src/coord.cpp +170 -0
  99. data/src/coord.h +35 -0
  100. data/src/font.cpp +118 -0
  101. data/src/font.h +64 -0
  102. data/src/frame_buffer.cpp +37 -71
  103. data/src/frame_buffer.h +4 -4
  104. data/src/image.cpp +172 -98
  105. data/src/image.h +25 -0
  106. data/src/ios/bitmap.h +21 -0
  107. data/src/ios/bitmap.mm +129 -110
  108. data/src/ios/camera.mm +236 -0
  109. data/src/ios/font.mm +50 -62
  110. data/src/ios/helper.h +2 -2
  111. data/src/ios/opengl.mm +19 -4
  112. data/src/ios/rays.mm +3 -0
  113. data/src/matrix.cpp +111 -26
  114. data/src/matrix.h +30 -0
  115. data/src/noise.cpp +74 -0
  116. data/src/opengl.cpp +9 -27
  117. data/src/opengl.h +37 -0
  118. data/src/osx/bitmap.h +21 -0
  119. data/src/osx/bitmap.mm +129 -110
  120. data/src/osx/camera.mm +236 -0
  121. data/src/osx/font.mm +49 -62
  122. data/src/osx/helper.h +2 -2
  123. data/src/osx/opengl.mm +19 -83
  124. data/src/osx/rays.mm +3 -0
  125. data/src/painter.cpp +845 -671
  126. data/src/painter.h +24 -0
  127. data/src/point.cpp +140 -119
  128. data/src/polygon.cpp +1266 -0
  129. data/src/polygon.h +32 -0
  130. data/src/polyline.cpp +160 -0
  131. data/src/polyline.h +69 -0
  132. data/src/render_buffer.cpp +11 -4
  133. data/src/render_buffer.h +2 -2
  134. data/src/shader.cpp +163 -106
  135. data/src/shader.h +38 -0
  136. data/src/shader_program.cpp +533 -0
  137. data/src/{program.h → shader_program.h} +28 -16
  138. data/src/shader_source.cpp +140 -0
  139. data/src/shader_source.h +52 -0
  140. data/src/texture.cpp +136 -160
  141. data/src/texture.h +65 -0
  142. data/src/win32/bitmap.cpp +62 -52
  143. data/src/win32/font.cpp +11 -13
  144. data/src/win32/font.h +24 -0
  145. data/src/win32/gdi.h +6 -6
  146. data/test/helper.rb +0 -3
  147. data/test/test_bitmap.rb +31 -7
  148. data/test/test_bounds.rb +36 -0
  149. data/test/test_color.rb +59 -19
  150. data/test/test_color_space.rb +95 -0
  151. data/test/test_font.rb +5 -0
  152. data/test/test_image.rb +24 -20
  153. data/test/test_matrix.rb +106 -0
  154. data/test/test_painter.rb +157 -51
  155. data/test/test_painter_shape.rb +102 -0
  156. data/test/test_point.rb +29 -0
  157. data/test/test_polygon.rb +234 -0
  158. data/test/test_polygon_line.rb +167 -0
  159. data/test/test_polyline.rb +171 -0
  160. data/test/test_shader.rb +9 -9
  161. metadata +102 -70
  162. data/.doc/ext/rays/texture.cpp +0 -138
  163. data/ext/rays/texture.cpp +0 -149
  164. data/include/rays/ruby/texture.h +0 -41
  165. data/include/rays/texture.h +0 -71
  166. data/lib/rays/texture.rb +0 -24
  167. data/src/program.cpp +0 -648
  168. data/test/test_texture.rb +0 -27
@@ -0,0 +1,25 @@
1
+ // -*- c++ -*-
2
+ #pragma once
3
+ #ifndef __RAYS_SRC_IMAGE_H__
4
+ #define __RAYS_SRC_IMAGE_H__
5
+
6
+
7
+ #include <rays/image.h>
8
+
9
+
10
+ namespace Rays
11
+ {
12
+
13
+
14
+ class Texture;
15
+
16
+
17
+ Texture& Image_get_texture ( Image& image);
18
+
19
+ const Texture& Image_get_texture (const Image& image);
20
+
21
+
22
+ }// Rays
23
+
24
+
25
+ #endif//EOH
@@ -0,0 +1,21 @@
1
+ // -*- mode: c++ -*-
2
+ #pragma once
3
+ #ifndef __RAYS_SRC_OSX_BITMAP_H__
4
+ #define __RAYS_SRC_OSX_BITMAP_H__
5
+
6
+
7
+ #import <CoreGraphics/CGImage.h>
8
+ #include "../bitmap.h"
9
+
10
+
11
+ namespace Rays
12
+ {
13
+
14
+
15
+ void Bitmap_copy_pixels (Bitmap* bitmap, CGImageRef image);
16
+
17
+
18
+ }// Rays
19
+
20
+
21
+ #endif//EOH
@@ -1,13 +1,13 @@
1
1
  // -*- objc -*-
2
- #import "rays/bitmap.h"
2
+ #import "bitmap.h"
3
3
 
4
4
 
5
- #include <assert.h>
6
- #include <boost/scoped_array.hpp>
7
- #import <ImageIO/ImageIO.h>
5
+ #import <ImageIO/CGImageDestination.h>
8
6
  #import <MobileCoreServices/UTCoreTypes.h>
9
7
  #include "rays/exception.h"
10
- #include "rays/texture.h"
8
+ #include "../color_space.h"
9
+ #include "../font.h"
10
+ #include "../texture.h"
11
11
  #include "../frame_buffer.h"
12
12
  #include "helper.h"
13
13
 
@@ -27,14 +27,14 @@ namespace Rays
27
27
  if (cs.is_alpha_first())
28
28
  {
29
29
  info |= cs.is_premult()
30
- ? kCGImageAlphaPremultipliedFirst
31
- : kCGImageAlphaFirst;
30
+ ? kCGImageAlphaPremultipliedFirst
31
+ : kCGImageAlphaFirst;
32
32
  }
33
33
  else if (cs.is_alpha_last())
34
34
  {
35
35
  info |= cs.is_premult()
36
- ? kCGImageAlphaPremultipliedLast
37
- : kCGImageAlphaLast;
36
+ ? kCGImageAlphaPremultipliedLast
37
+ : kCGImageAlphaLast;
38
38
  }
39
39
  else if (cs.is_skip_first())
40
40
  info |= kCGImageAlphaNoneSkipFirst;
@@ -60,14 +60,13 @@ namespace Rays
60
60
 
61
61
  ColorSpace color_space;
62
62
 
63
- void* pixels;
63
+ void* pixels = NULL;
64
64
 
65
- CGContextRef context;
65
+ CGContextRef context = NULL;
66
66
 
67
- bool dirty;
67
+ bool modified;
68
68
 
69
69
  Data ()
70
- : pixels(NULL), context(NULL)
71
70
  {
72
71
  clear();
73
72
  }
@@ -86,7 +85,7 @@ namespace Rays
86
85
  if (bpc <= 0 || pitch <= 0) return NULL;
87
86
 
88
87
  CGColorSpaceRef cgcs = NULL;
89
- if (color_space.is_gray())
88
+ if (color_space.is_gray() || color_space.is_alpha())
90
89
  cgcs = CGColorSpaceCreateDeviceGray();
91
90
  else if (color_space.is_rgb() || color_space.is_bgr())
92
91
  cgcs = CGColorSpaceCreateDeviceRGB();
@@ -115,7 +114,7 @@ namespace Rays
115
114
  color_space = COLORSPACE_UNKNOWN;
116
115
  pixels = NULL;
117
116
  context = NULL;
118
- dirty = false;
117
+ modified = false;
119
118
  }
120
119
 
121
120
  };// Bitmap::Data
@@ -135,7 +134,7 @@ namespace Rays
135
134
  this_->self->width = w;
136
135
  this_->self->height = h;
137
136
  this_->self->color_space = cs;
138
- this_->self->dirty = true;
137
+ this_->self->modified = true;
139
138
 
140
139
  size_t size = w * h * cs.Bpp();
141
140
  this_->self->pixels = new uchar[size];
@@ -152,16 +151,122 @@ namespace Rays
152
151
  if (!this_ || !tex)
153
152
  argument_error(__FILE__, __LINE__);
154
153
 
155
- setup_bitmap(this_, tex.width(), tex.height(), tex.color_space(), NULL, false);
154
+ setup_bitmap(
155
+ this_, tex.width(), tex.height(), tex.color_space(), NULL, false);
156
156
 
157
157
  GLenum format, type;
158
- tex.color_space().get_gl_enums(&format, &type, tex.alpha_only());
158
+ ColorSpace_get_gl_format_and_type(&format, &type, tex.color_space());
159
159
 
160
160
  FrameBuffer fb(tex);
161
161
  FrameBufferBinder binder(fb.id());
162
162
 
163
163
  for (int y = 0; y < this_->height(); ++y)
164
- glReadPixels(0, y, this_->width(), 1, format, type, (GLvoid*) this_->at<uchar>(0, y));
164
+ {
165
+ GLvoid* ptr = (GLvoid*) this_->at<uchar>(0, y);
166
+ glReadPixels(0, y, this_->width(), 1, format, type, ptr);
167
+ }
168
+ }
169
+
170
+ Bitmap
171
+ Bitmap_from (const Texture& texture)
172
+ {
173
+ Bitmap bmp;
174
+ setup_bitmap(&bmp, texture);
175
+ return bmp;
176
+ }
177
+
178
+ void
179
+ Bitmap_copy_pixels (Bitmap* bitmap, CGImageRef image)
180
+ {
181
+ if (!bitmap || !image)
182
+ argument_error(__FILE__, __LINE__);
183
+
184
+ CGContextRef context = bitmap->self->get_context();
185
+ if (!context)
186
+ rays_error(__FILE__, __LINE__, "getting CGContext failed.");
187
+
188
+ size_t width = CGImageGetWidth(image);
189
+ size_t height = CGImageGetHeight(image);
190
+ CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
191
+
192
+ Bitmap_set_modified(bitmap);
193
+ }
194
+
195
+ void
196
+ Bitmap_draw_string (
197
+ Bitmap* bitmap, const RawFont& font, const char* str, coord x, coord y)
198
+ {
199
+ if (!bitmap || !*bitmap || !font || !str)
200
+ argument_error(__FILE__, __LINE__);
201
+
202
+ if (*str == '\0') return;
203
+
204
+ font.draw_string(bitmap->self->get_context(), bitmap->height(), str, x, y);
205
+
206
+ Bitmap_set_modified(bitmap);
207
+ }
208
+
209
+ void
210
+ Bitmap_set_modified (Bitmap* bitmap, bool modified)
211
+ {
212
+ assert(bitmap);
213
+
214
+ bitmap->self->modified = modified;
215
+ }
216
+
217
+ bool
218
+ Bitmap_get_modified (const Bitmap& bitmap)
219
+ {
220
+ return bitmap.self->modified;
221
+ }
222
+
223
+ void
224
+ Bitmap_save (const Bitmap& bmp, const char* path_)
225
+ {
226
+ std::shared_ptr<CGImage> img(bmp.self->get_image(), CGImageRelease);
227
+ if (!img)
228
+ rays_error(__FILE__, __LINE__, "getting CGImage failed.");
229
+
230
+ NSString* path = [NSString stringWithUTF8String: path_];
231
+ NSURL* url = [NSURL fileURLWithPath: path];
232
+ if (!url)
233
+ rays_error(__FILE__, __LINE__, "creating NSURL failed.");
234
+
235
+ std::shared_ptr<CGImageDestination> dest(
236
+ CGImageDestinationCreateWithURL((CFURLRef) url, kUTTypePNG, 1, NULL),
237
+ safe_cfrelease);
238
+ if (!dest)
239
+ rays_error(__FILE__, __LINE__, "CGImageDestinationCreateWithURL() failed.");
240
+
241
+ CGImageDestinationAddImage(dest.get(), img.get(), NULL);
242
+ if (!CGImageDestinationFinalize(dest.get()))
243
+ rays_error(__FILE__, __LINE__, "CGImageDestinationFinalize() failed.");
244
+ }
245
+
246
+ Bitmap
247
+ Bitmap_load (const char* path_)
248
+ {
249
+ if (!path_ || path_[0] == '\0')
250
+ argument_error(__FILE__, __LINE__);
251
+
252
+ NSString* path = [NSString stringWithUTF8String: path_];
253
+ UIImage* uiimage = [UIImage imageWithContentsOfFile: path];
254
+ if (!uiimage)
255
+ rays_error(__FILE__, __LINE__, "[UIImage imageWithContentsOfFile:] failed.");
256
+
257
+ CGImageRef image = [uiimage CGImage];
258
+ if (!image)
259
+ rays_error(__FILE__, __LINE__, "[imagerep CGImage] failed.");
260
+
261
+ size_t width = CGImageGetWidth(image);
262
+ size_t height = CGImageGetHeight(image);
263
+
264
+ Bitmap bmp((int) width, (int) height, RGBA);
265
+ if (!bmp)
266
+ rays_error(__FILE__, __LINE__, "invalid bitmap.");
267
+
268
+ Bitmap_copy_pixels(&bmp, image);
269
+ return bmp;
165
270
  }
166
271
 
167
272
 
@@ -175,17 +280,12 @@ namespace Rays
175
280
  setup_bitmap(this, width, height, color_space, pixels);
176
281
  }
177
282
 
178
- Bitmap::Bitmap (const Texture& texture)
179
- {
180
- setup_bitmap(this, texture);
181
- }
182
-
183
283
  Bitmap::~Bitmap ()
184
284
  {
185
285
  }
186
286
 
187
287
  Bitmap
188
- Bitmap::copy () const
288
+ Bitmap::dup () const
189
289
  {
190
290
  return Bitmap(width(), height(), color_space(), pixels());
191
291
  }
@@ -240,22 +340,13 @@ namespace Rays
240
340
  return const_cast<This*>(this)->pixels();
241
341
  }
242
342
 
243
- bool
244
- Bitmap::dirty () const
245
- {
246
- return self->dirty;
247
- }
248
-
249
- void
250
- Bitmap::set_dirty (bool b)
251
- {
252
- self->dirty = b;
253
- }
254
-
255
343
  Bitmap::operator bool () const
256
344
  {
257
345
  return
258
- self->width > 0 && self->height > 0 && self->color_space && self->pixels;
346
+ self->width > 0 &&
347
+ self->height > 0 &&
348
+ self->color_space &&
349
+ self->pixels;
259
350
  }
260
351
 
261
352
  bool
@@ -265,76 +356,4 @@ namespace Rays
265
356
  }
266
357
 
267
358
 
268
- Bitmap
269
- load_bitmap (const char* path_)
270
- {
271
- if (!path_ || path_[0] == '\0')
272
- argument_error(__FILE__, __LINE__);
273
-
274
- NSString* path = [NSString stringWithUTF8String: path_];
275
- UIImage* uiimage = [UIImage imageWithContentsOfFile: path];
276
- if (!uiimage)
277
- rays_error(__FILE__, __LINE__, "[UIImage imageWithContentsOfFile:] failed.");
278
-
279
- CGImageRef image = [uiimage CGImage];
280
- if (!image)
281
- rays_error(__FILE__, __LINE__, "[imagerep CGImage] failed.");
282
-
283
- size_t width = CGImageGetWidth(image);
284
- size_t height = CGImageGetHeight(image);
285
-
286
- Bitmap bmp((int) width, (int) height, RGBA);
287
- if (!bmp)
288
- rays_error(__FILE__, __LINE__, "invalid bitmap.");
289
-
290
- CGContextRef context = bmp.self->get_context();
291
- if (!context)
292
- rays_error(__FILE__, __LINE__, "creating CGContext failed.");
293
-
294
- CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
295
- return bmp;
296
- }
297
-
298
- void
299
- save_bitmap (const Bitmap& bmp, const char* path_)
300
- {
301
- boost::shared_ptr<CGImage> img(
302
- bmp.self->get_image(), CGImageRelease);
303
- if (!img)
304
- rays_error(__FILE__, __LINE__, "getting CGImage failed.");
305
-
306
- NSString* path = [NSString stringWithUTF8String: path_];
307
- NSURL* url = [NSURL fileURLWithPath: path];
308
- if (!url)
309
- rays_error(__FILE__, __LINE__, "creating NSURL failed.");
310
-
311
- boost::shared_ptr<CGImageDestination> dest(
312
- CGImageDestinationCreateWithURL((CFURLRef) url, kUTTypePNG, 1, NULL),
313
- safe_cfrelease);
314
- if (!dest)
315
- rays_error(__FILE__, __LINE__, "CGImageDestinationCreateWithURL() failed.");
316
-
317
- CGImageDestinationAddImage(dest.get(), img.get(), NULL);
318
- if (!CGImageDestinationFinalize(dest.get()))
319
- rays_error(__FILE__, __LINE__, "CGImageDestinationFinalize() failed.");
320
- }
321
-
322
-
323
- void draw_string (
324
- CGContextRef, coord, const char*, coord, coord, const Font&);
325
-
326
- void
327
- draw_string (
328
- Bitmap* bmp, const char* str, coord x, coord y, const Font& font)
329
- {
330
- if (!bmp || !*bmp || !str || !font)
331
- argument_error(__FILE__, __LINE__);
332
-
333
- if (*str == '\0') return;
334
-
335
- draw_string(bmp->self->get_context(), bmp->height(), str, x, y, font);
336
- bmp->set_dirty();
337
- }
338
-
339
-
340
359
  }// Rays
@@ -0,0 +1,236 @@
1
+ // -*- mode: objc -*-
2
+ #import "rays/camera.h"
3
+
4
+
5
+ #import <AVFoundation/AVFoundation.h>
6
+ #include "bitmap.h"
7
+
8
+
9
+ static int video_input_queue_index = 0;
10
+
11
+
12
+ @interface VideoInput : NSObject <AVCaptureVideoDataOutputSampleBufferDelegate>
13
+ @end
14
+
15
+
16
+ @implementation VideoInput
17
+
18
+ {
19
+ AVCaptureSession* captureSession;
20
+ dispatch_queue_t captureQueue;
21
+ CGImageRef captureImage;
22
+ }
23
+
24
+ - (id) init
25
+ {
26
+ self = [super init];
27
+ if (self)
28
+ {
29
+ captureSession = nil;
30
+ captureQueue = nil;
31
+ captureImage = nil;
32
+ }
33
+ return self;
34
+ }
35
+
36
+ - (void) dealloc
37
+ {
38
+ [self stop];
39
+ [self clearImage];
40
+
41
+ if (captureQueue)
42
+ {
43
+ dispatch_release(captureQueue);
44
+ captureQueue = nil;
45
+ }
46
+
47
+ [super dealloc];
48
+ }
49
+
50
+ - (dispatch_queue_t) queue
51
+ {
52
+ if (!captureQueue)
53
+ {
54
+ auto name = Xot::stringf(
55
+ "org.xord.RaysVideoInputQueue_%d",
56
+ video_input_queue_index++);
57
+ captureQueue = dispatch_queue_create(name, DISPATCH_QUEUE_SERIAL);
58
+ }
59
+ return captureQueue;
60
+ }
61
+
62
+ - (BOOL) start
63
+ {
64
+ [self stop];
65
+
66
+ AVCaptureSession* session = [[[AVCaptureSession alloc] init] autorelease];
67
+ session.sessionPreset = AVCaptureSessionPresetHigh;
68
+
69
+ AVCaptureDevice* device =
70
+ [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];
71
+ if (!device) return NO;
72
+
73
+ //device.activeVideoMinFrameDuration = CMTimeMake(1, 30);
74
+
75
+ NSError* error = nil;
76
+ AVCaptureDeviceInput* input = [[[AVCaptureDeviceInput alloc]
77
+ initWithDevice: device error: &error]
78
+ autorelease];
79
+ if (!input || error || ![session canAddInput: input])
80
+ return NO;
81
+
82
+ AVCaptureVideoDataOutput* output =
83
+ [[[AVCaptureVideoDataOutput alloc] init] autorelease];
84
+ output.videoSettings = @{
85
+ (NSString*) kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)
86
+ };
87
+ output.alwaysDiscardsLateVideoFrames = YES;
88
+ [output setSampleBufferDelegate: self queue: self.queue];
89
+ if (![session canAddOutput: output])
90
+ return NO;
91
+
92
+ [session addInput: input];
93
+ [session addOutput: output];
94
+ [session startRunning];
95
+
96
+ captureSession = [session retain];
97
+ return YES;
98
+ }
99
+
100
+ - (void) captureOutput: (AVCaptureOutput*) output
101
+ didOutputSampleBuffer: (CMSampleBufferRef) sampleBuffer
102
+ fromConnection: (AVCaptureConnection*) connection
103
+ {
104
+ CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
105
+ if (!pixelBuffer) return;
106
+
107
+ CIImage* ciImage = [CIImage imageWithCVPixelBuffer: pixelBuffer];
108
+ if (!ciImage) return;
109
+
110
+ CIContext* context = [CIContext contextWithOptions: nil];
111
+ size_t width = CVPixelBufferGetWidth(pixelBuffer);
112
+ size_t height = CVPixelBufferGetHeight(pixelBuffer);
113
+ CGRect rect = CGRectMake(0, 0, width, height);
114
+ CGImageRef cgImage = [context createCGImage: ciImage fromRect: rect];
115
+
116
+ dispatch_async(dispatch_get_main_queue(), ^{
117
+ [self clearImage];
118
+ captureImage = cgImage;
119
+ });
120
+ }
121
+
122
+ - (void) stop
123
+ {
124
+ if (!captureSession) return;
125
+
126
+ [captureSession stopRunning];
127
+ [captureSession release];
128
+ captureSession = nil;
129
+ }
130
+
131
+ - (BOOL) isActive
132
+ {
133
+ return captureSession != nil;
134
+ }
135
+
136
+ - (void) clearImage
137
+ {
138
+ if (!captureImage) return;
139
+
140
+ CGImageRelease(captureImage);
141
+ captureImage = nil;
142
+ }
143
+
144
+ - (CGImageRef) getImage
145
+ {
146
+ return captureImage;
147
+ }
148
+
149
+ @end// VideoInput
150
+
151
+
152
+ namespace Rays
153
+ {
154
+
155
+
156
+ struct Camera::Data
157
+ {
158
+
159
+ mutable Image image;
160
+
161
+ VideoInput* video_input = nil;
162
+
163
+ void update_image_from_video_input () const
164
+ {
165
+ if (!video_input) return;
166
+
167
+ CGImageRef cgImage = [video_input getImage];
168
+ if (!cgImage) return;
169
+
170
+ if (!image)
171
+ {
172
+ Bitmap bmp(
173
+ (int) CGImageGetWidth(cgImage),
174
+ (int) CGImageGetHeight(cgImage));
175
+ image = Image(bmp);
176
+ }
177
+
178
+ Bitmap_copy_pixels(&image.bitmap(), cgImage);
179
+
180
+ [video_input clearImage];
181
+ }
182
+
183
+ };// Camera::Data
184
+
185
+
186
+ Camera::Camera ()
187
+ {
188
+ }
189
+
190
+ Camera::~Camera ()
191
+ {
192
+ stop();
193
+ if (self->video_input) [self->video_input release];
194
+ }
195
+
196
+ bool
197
+ Camera::start ()
198
+ {
199
+ if (!self->video_input) self->video_input = [[VideoInput alloc] init];
200
+ return [self->video_input start];
201
+ }
202
+
203
+ void
204
+ Camera::stop ()
205
+ {
206
+ if (!self->video_input) return;
207
+
208
+ [self->video_input stop];
209
+ }
210
+
211
+ bool
212
+ Camera::is_active () const
213
+ {
214
+ return self->video_input && [self->video_input isActive];
215
+ }
216
+
217
+ const Image*
218
+ Camera::image () const
219
+ {
220
+ self->update_image_from_video_input();
221
+ return self->image ? &self->image : NULL;
222
+ }
223
+
224
+ Camera::operator bool () const
225
+ {
226
+ return true;
227
+ }
228
+
229
+ bool
230
+ Camera::operator ! () const
231
+ {
232
+ return !operator bool();
233
+ }
234
+
235
+
236
+ }// Rays