CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/external/source/osx/isight/CSGCamera.m
Views: 11779
1
//
2
// CSGCamera.m
3
// MotionTracker
4
//
5
// Created by Tim Omernick on 3/7/05.
6
// Copyright 2005 Tim Omernick. All rights reserved.
7
//
8
9
// Portions of this file were inspired by Apple Computer, Inc.'s Cocoa SGDataProc example, which can be found here:
10
// <http://developer.apple.com/samplecode/Cocoa_-_SGDataProc/Cocoa_-_SGDataProc.html>
11
// Also, I'd like to thank Chris Meyer for his excellent -imageFromGWorld: method, which he gave me permission to use for this framework.
12
13
#import "CSGCamera.h"
14
15
#import "CSGImage.h"
16
17
@interface CSGCamera (Private)
18
- (void)_sequenceGrabberIdle;
19
- (BOOL)_setupDecompression;
20
- (void)_didUpdate;
21
- (CSGImage *)_imageFromGWorld:(GWorldPtr)gworld;
22
@end
23
24
@interface CSGCamera (SequenceGrabber)
25
pascal OSErr CSGCameraSGDataProc(SGChannel channel, Ptr data, long dataLength, long *offset, long channelRefCon, TimeValue time, short writeType, long refCon);
26
@end
27
28
@implementation CSGCamera
29
30
// Init and dealloc
31
32
- (void)dealloc;
33
{
34
[self stop];
35
36
[delegate release];
37
38
[super dealloc];
39
}
40
41
// API
42
43
- (void)setDelegate:(id)newDelegate;
44
{
45
if (delegate == newDelegate)
46
return;
47
48
[delegate release];
49
delegate = [newDelegate retain];
50
}
51
52
- (BOOL)startWithSize:(NSSize)frameSize;
53
{
54
OSErr theErr;
55
56
timeScale = 0;
57
lastTime = 0;
58
59
// Initialize movie toolbox
60
theErr = EnterMovies();
61
if (theErr != noErr) {
62
NSLog(@"EnterMovies() returned %ld", theErr);
63
return NO;
64
}
65
66
// Open default sequence grabber component
67
component = OpenDefaultComponent(SeqGrabComponentType, 0);
68
if (!component) {
69
NSLog(@"Could not open sequence grabber component.");
70
return NO;
71
}
72
73
// Initialize sequence grabber component
74
theErr = SGInitialize(component);
75
if (theErr != noErr) {
76
NSLog(@"SGInitialize() returned %ld", theErr);
77
return NO;
78
}
79
80
// Don't make movie
81
theErr = SGSetDataRef(component, 0, 0, seqGrabDontMakeMovie);
82
if (theErr != noErr) {
83
NSLog(@"SGSetDataRef() returned %ld", theErr);
84
return NO;
85
}
86
87
// Create sequence grabber video channel
88
theErr = SGNewChannel(component, VideoMediaType, &channel);
89
if (theErr != noErr) {
90
NSLog(@"SGNewChannel() returned %ld", theErr);
91
return NO;
92
}
93
94
// Set the grabber's bounds
95
boundsRect.top = 0;
96
boundsRect.left = 0;
97
boundsRect.bottom = frameSize.height;
98
boundsRect.right = frameSize.width;
99
100
// NSLog(@"boundsRect=(%d, %d, %d, %d)", boundsRect.top, boundsRect.left, boundsRect.bottom, boundsRect.right);
101
102
theErr = SGSetChannelBounds(component, &boundsRect);
103
104
// Create the GWorld
105
theErr = QTNewGWorld(&gWorld, k32ARGBPixelFormat, &boundsRect, 0, NULL, 0);
106
if (theErr != noErr) {
107
NSLog(@"QTNewGWorld() returned %ld", theErr);
108
return NO;
109
}
110
111
// Lock the pixmap
112
if (!LockPixels(GetPortPixMap(gWorld))) {
113
NSLog(@"Could not lock pixels.");
114
return NO;
115
}
116
117
// Set GWorld
118
theErr = SGSetGWorld(component, gWorld, GetMainDevice());
119
if (theErr != noErr) {
120
NSLog(@"SGSetGWorld() returned %ld", theErr);
121
return NO;
122
}
123
124
// Set the channel's bounds
125
theErr = SGSetChannelBounds(channel, &boundsRect);
126
if (theErr != noErr) {
127
NSLog(@"SGSetChannelBounds(2) returned %ld", theErr);
128
return NO;
129
}
130
131
// Set the channel usage to record
132
theErr = SGSetChannelUsage(channel, seqGrabRecord);
133
if (theErr != noErr) {
134
NSLog(@"SGSetChannelUsage() returned %ld", theErr);
135
return NO;
136
}
137
138
// Set data proc
139
theErr = SGSetDataProc(component, NewSGDataUPP(&CSGCameraSGDataProc), (long)self);
140
if (theErr != noErr) {
141
NSLog(@"SGSetDataProc() returned %ld", theErr);
142
return NO;
143
}
144
145
// Prepare
146
theErr = SGPrepare(component, false, true);
147
if (theErr != noErr) {
148
NSLog(@"SGPrepare() returned %ld", theErr);
149
return NO;
150
}
151
152
// Start recording
153
theErr = SGStartRecord(component);
154
if (theErr != noErr) {
155
NSLog(@"SGStartRecord() returned %ld", theErr);
156
return NO;
157
}
158
159
startTime = [NSDate timeIntervalSinceReferenceDate];
160
161
// Set up decompression sequence (camera -> GWorld)
162
[self _setupDecompression];
163
164
// Start frame timer
165
frameTimer = [[NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(_sequenceGrabberIdle) userInfo:nil repeats:YES] retain];
166
167
[self retain]; // Matches autorelease in -stop
168
169
return YES;
170
}
171
172
- (BOOL)stop;
173
{
174
// Stop frame timer
175
if (frameTimer) {
176
[frameTimer invalidate];
177
[frameTimer release];
178
frameTimer = nil;
179
}
180
181
// Stop recording
182
if (component)
183
SGStop(component);
184
185
ComponentResult theErr;
186
187
// End decompression sequence
188
if (decompressionSequence) {
189
theErr = CDSequenceEnd(decompressionSequence);
190
if (theErr != noErr) {
191
NSLog(@"CDSequenceEnd() returned %ld", theErr);
192
}
193
decompressionSequence = 0;
194
}
195
196
// Close sequence grabber component
197
if (component) {
198
theErr = CloseComponent(component);
199
if (theErr != noErr) {
200
NSLog(@"CloseComponent() returned %ld", theErr);
201
}
202
component = NULL;
203
}
204
205
// Dispose of GWorld
206
if (gWorld) {
207
DisposeGWorld(gWorld);
208
gWorld = NULL;
209
}
210
211
[self autorelease]; // Matches retain in -start
212
213
return YES;
214
}
215
216
@end
217
218
@implementation CSGCamera (Private)
219
220
- (void)_sequenceGrabberIdle;
221
{
222
OSErr theErr;
223
224
theErr = SGIdle(component);
225
if (theErr != noErr) {
226
NSLog(@"SGIdle returned %ld", theErr);
227
return;
228
}
229
}
230
231
- (BOOL)_setupDecompression;
232
{
233
ComponentResult theErr;
234
235
ImageDescriptionHandle imageDesc = (ImageDescriptionHandle)NewHandle(0);
236
theErr = SGGetChannelSampleDescription(channel, (Handle)imageDesc);
237
if (theErr != noErr) {
238
NSLog(@"SGGetChannelSampleDescription() returned %ld", theErr);
239
return NO;
240
}
241
242
Rect sourceRect;
243
sourceRect.top = 0;
244
sourceRect.left = 0;
245
sourceRect.right = (**imageDesc).width;
246
sourceRect.bottom = (**imageDesc).height;
247
248
MatrixRecord scaleMatrix;
249
RectMatrix(&scaleMatrix, &sourceRect, &boundsRect);
250
251
theErr = DecompressSequenceBegin(&decompressionSequence, imageDesc, gWorld, NULL, NULL, &scaleMatrix, srcCopy, NULL, 0, codecNormalQuality, bestSpeedCodec);
252
if (theErr != noErr) {
253
NSLog(@"DecompressionSequenceBegin() returned %ld", theErr);
254
return NO;
255
}
256
257
DisposeHandle((Handle)imageDesc);
258
259
return YES;
260
}
261
262
- (void)_didUpdate;
263
{
264
if ([delegate respondsToSelector:@selector(camera:didReceiveFrame:)]) {
265
CSGImage *frameImage = [self _imageFromGWorld:gWorld];
266
if (frameImage) {
267
[frameImage setSampleTime:startTime + ((double)lastTime / (double)timeScale)];
268
[delegate camera:self didReceiveFrame:frameImage];
269
}
270
}
271
}
272
273
// Thanks to Chris Meyer from http://www.cocoadev.com/
274
- (CSGImage *)_imageFromGWorld:(GWorldPtr)gworld;
275
{
276
NSParameterAssert( gworld != NULL );
277
278
PixMapHandle pixMapHandle = GetGWorldPixMap( gworld );
279
if ( LockPixels( pixMapHandle ) )
280
{
281
Rect portRect;
282
GetPortBounds( gworld, &portRect );
283
int pixels_wide = (portRect.right - portRect.left);
284
int pixels_high = (portRect.bottom - portRect.top);
285
286
int bps = 8;
287
int spp = 4;
288
BOOL has_alpha = YES;
289
290
NSBitmapImageRep *frameBitmap = [[[NSBitmapImageRep alloc]
291
initWithBitmapDataPlanes:NULL
292
pixelsWide:pixels_wide
293
pixelsHigh:pixels_high
294
bitsPerSample:bps
295
samplesPerPixel:spp
296
hasAlpha:has_alpha
297
isPlanar:NO
298
colorSpaceName:NSDeviceRGBColorSpace
299
bytesPerRow:0
300
bitsPerPixel:0] autorelease];
301
302
CGColorSpaceRef dst_colorspaceref = CGColorSpaceCreateDeviceRGB();
303
304
CGImageAlphaInfo dst_alphainfo = has_alpha ? kCGImageAlphaPremultipliedLast : kCGImageAlphaNone;
305
306
CGContextRef dst_contextref = CGBitmapContextCreate( [frameBitmap bitmapData],
307
pixels_wide,
308
pixels_high,
309
bps,
310
[frameBitmap bytesPerRow],
311
dst_colorspaceref,
312
dst_alphainfo );
313
314
void *pixBaseAddr = GetPixBaseAddr(pixMapHandle);
315
316
long pixmapRowBytes = GetPixRowBytes(pixMapHandle);
317
318
CGDataProviderRef dataproviderref = CGDataProviderCreateWithData( NULL, pixBaseAddr, pixmapRowBytes * pixels_high, NULL );
319
320
int src_bps = 8;
321
int src_spp = 4;
322
BOOL src_has_alpha = YES;
323
324
CGColorSpaceRef src_colorspaceref = CGColorSpaceCreateDeviceRGB();
325
326
CGImageAlphaInfo src_alphainfo = src_has_alpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNone;
327
328
CGImageRef src_imageref = CGImageCreate( pixels_wide,
329
pixels_high,
330
src_bps,
331
src_bps * src_spp,
332
pixmapRowBytes,
333
src_colorspaceref,
334
src_alphainfo,
335
dataproviderref,
336
NULL,
337
NO, // shouldInterpolate
338
kCGRenderingIntentDefault );
339
340
CGRect rect = CGRectMake( 0, 0, pixels_wide, pixels_high );
341
342
CGContextDrawImage( dst_contextref, rect, src_imageref );
343
344
CGImageRelease( src_imageref );
345
CGColorSpaceRelease( src_colorspaceref );
346
CGDataProviderRelease( dataproviderref );
347
CGContextRelease( dst_contextref );
348
CGColorSpaceRelease( dst_colorspaceref );
349
350
UnlockPixels( pixMapHandle );
351
352
CSGImage *image = [[CSGImage alloc] initWithSize:NSMakeSize(pixels_wide, pixels_high)];
353
[image addRepresentation:frameBitmap];
354
355
return [image autorelease];
356
}
357
358
return NULL;
359
}
360
361
@end
362
363
@implementation CSGCamera (SequenceGrabber)
364
365
pascal OSErr CSGCameraSGDataProc(SGChannel channel, Ptr data, long dataLength, long *offset, long channelRefCon, TimeValue time, short writeType, long refCon)
366
{
367
CSGCamera *camera = (CSGCamera *)refCon;
368
ComponentResult theErr;
369
370
if (camera->timeScale == 0) {
371
theErr = SGGetChannelTimeScale(camera->channel, &camera->timeScale);
372
if (theErr != noErr) {
373
NSLog(@"SGGetChannelTimeScale() returned %ld", theErr);
374
return theErr;
375
}
376
}
377
378
if (camera->gWorld) {
379
CodecFlags ignore;
380
theErr = DecompressSequenceFrameS(camera->decompressionSequence, data, dataLength, 0, &ignore, NULL);
381
if (theErr != noErr) {
382
NSLog(@"DecompressSequenceFrameS() returned %ld", theErr);
383
return theErr;
384
}
385
}
386
387
camera->lastTime = time;
388
389
[camera _didUpdate];
390
391
return noErr;
392
}
393
394
@end
395
396