rays 0.1.11 → 0.1.16

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.
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