12 #include <OpenGL/CGLMacro.h>
13 #include <QuartzCore/CoreImage.h>
14 #include <QuartzCore/CoreVideo.h>
16 #pragma clang diagnostic push
17 #pragma clang diagnostic ignored "-Wdocumentation"
18 #include <json-c/json.h>
19 #pragma clang diagnostic pop
30 #include "../node/node.h"
40 + (id)cocoaObjectWithVuoValue:(
json_object *)vuoValue ofType:(
string)type
42 if (type ==
"VuoBoolean")
45 return [NSNumber numberWithBool:v];
47 if (type ==
"VuoList_VuoBoolean")
51 NSMutableArray *a = [[NSMutableArray new] autorelease];
52 for (
unsigned long i=0; i<count; ++i)
53 [a addObject:[NSNumber numberWithBool:VuoListGetValue_VuoBoolean(l, i+1)]];
57 if (type ==
"VuoInteger")
60 return [NSNumber numberWithLong:v];
62 if (type ==
"VuoList_VuoInteger")
66 NSMutableArray *a = [[NSMutableArray new] autorelease];
67 for (
unsigned long i=0; i<count; ++i)
68 [a addObject:[NSNumber numberWithLong:VuoListGetValue_VuoInteger(l, i+1)]];
72 if (type ==
"VuoReal")
75 return [NSNumber numberWithDouble:v];
77 if (type ==
"VuoList_VuoReal")
81 NSMutableArray *a = [[NSMutableArray new] autorelease];
82 for (
unsigned long i=0; i<count; ++i)
83 [a addObject:[NSNumber numberWithDouble:VuoListGetValue_VuoReal(l, i+1)]];
87 if (type ==
"VuoText")
91 NSString *s = [NSString stringWithUTF8String:v];
95 if (type ==
"VuoList_VuoText")
99 NSMutableArray *a = [[NSMutableArray new] autorelease];
100 for (
unsigned long i=0; i<count; ++i)
101 [a addObject:[NSString stringWithUTF8String:VuoListGetValue_VuoText(l, i+1)]];
105 if (type ==
"VuoColor")
108 CGFloat c[4] = {v.r, v.g, v.b, v.a};
109 return [NSColor colorWithColorSpace:[NSColorSpace sRGBColorSpace] components:c count:4];
111 if (type ==
"VuoList_VuoColor")
115 NSMutableArray *a = [[NSMutableArray new] autorelease];
116 for (
unsigned long i=0; i<count; ++i)
119 CGFloat c[4] = {v.r, v.g, v.b, v.a};
120 [a addObject:[NSColor colorWithColorSpace:[NSColorSpace sRGBColorSpace] components:c count:4]];
125 if (type ==
"VuoImage")
129 NSImage *im = [
self nsImageWithVuoImage:v];
133 if (type ==
"VuoList_VuoImage")
137 NSMutableArray *a = [[NSMutableArray new] autorelease];
138 for (
unsigned long i=0; i<count; ++i)
142 [a addObject:[
self nsImageWithVuoImage:v]];
148 if (type ==
"VuoPoint2d")
151 return [NSValue valueWithPoint:NSMakePoint(v.x, v.y)];
153 if (type ==
"VuoList_VuoPoint2d")
157 NSMutableArray *a = [[NSMutableArray new] autorelease];
158 for (
unsigned long i=0; i<count; ++i)
161 [a addObject:[NSValue valueWithPoint:NSMakePoint(v.x, v.y)]];
166 if (type ==
"VuoPoint3d")
169 size_t s =
sizeof(double)*3;
170 double *d = (
double *)malloc(s);
174 return [NSData dataWithBytesNoCopy:d length:s];
176 if (type ==
"VuoList_VuoPoint3d")
180 NSMutableArray *a = [[NSMutableArray new] autorelease];
181 for (
unsigned long i=0; i<count; ++i)
184 size_t s =
sizeof(double)*3;
185 double *d = (
double *)malloc(s);
189 [a addObject:[NSData dataWithBytesNoCopy:d length:s]];
198 string allowedValuesFunctionName = itemType + "_getAllowedValues";
199 typedef void *(*allowedValuesFunctionType)(void);
200 allowedValuesFunctionType allowedValuesFunction = (allowedValuesFunctionType)dlsym(RTLD_SELF, allowedValuesFunctionName.c_str());
201 if (allowedValuesFunction)
202 if (json_object_is_type(vuoValue, json_type_array))
204 unsigned long arrayLength = json_object_array_length(vuoValue);
206 return [[NSArray new] autorelease];
208 else if (json_object_is_type(json_object_array_get_idx(vuoValue, 0), json_type_string))
210 NSMutableArray *a = [[NSMutableArray new] autorelease];
211 for (
unsigned long i = 0; i < arrayLength; ++i)
212 [a addObject:[NSString stringWithUTF8String:json_object_get_string(json_object_array_get_idx(vuoValue, i))]];
219 string allowedValuesFunctionName = type + "_getAllowedValues";
220 typedef void *(*allowedValuesFunctionType)(void);
221 allowedValuesFunctionType allowedValuesFunction = (allowedValuesFunctionType)dlsym(RTLD_SELF, allowedValuesFunctionName.c_str());
222 if (allowedValuesFunction)
223 if (json_object_is_type(vuoValue, json_type_string))
224 return [NSString stringWithUTF8String:json_object_get_string(vuoValue)];
226 VUserLog(
"Type %s isn't supported yet. Please https://vuo.org/contact us if you'd like support for this type.", type.c_str());
233 static void VuoRunnerCocoa_doNothingCallback(
VuoImage imageToFree)
248 if ([value respondsToSelector:
@selector(vuoValue)])
249 return [value vuoValue];
252 if (strcmp(object_getClassName(value),
"__NSCFType") == 0)
254 CFTypeID type = CFGetTypeID(value);
256 if (type == CGColorGetTypeID())
258 NSColorSpace *nscs = [[NSColorSpace alloc] initWithCGColorSpace:CGColorGetColorSpace((CGColorRef)value)];
259 NSColor *color = [NSColor colorWithColorSpace:nscs components:CGColorGetComponents((CGColorRef)value) count:CGColorGetNumberOfComponents((CGColorRef)value)];
261 return [color vuoValue];
264 if (type == CGImageGetTypeID())
266 CGImageRef cgimage = (CGImageRef)value;
268 if (CGImageGetAlphaInfo(cgimage) != kCGImageAlphaPremultipliedLast)
270 VUserLog(
"Error: Alpha option %d isn't supported yet. Please use kCGImageAlphaPremultipliedLast, and https://vuo.org/contact us if you'd like support for other alpha options.", CGImageGetAlphaInfo(cgimage));
274 if (CGImageGetBitmapInfo(cgimage) & kCGBitmapFloatComponents)
276 VUserLog(
"Error: Floating-point pixel values aren't supported yet. Please use integer pixel values, and https://vuo.org/contact us if you'd like support for floating-point pixel values.");
280 if (CGImageGetBitsPerComponent(cgimage) != 8)
282 VUserLog(
"Error: BitsPerComponent=%lu isn't supported yet. Please use 8 bits per component, and https://vuo.org/contact us if you'd like support for other bit depths.", CGImageGetBitsPerComponent(cgimage));
286 if (CGImageGetBitsPerPixel(cgimage) != 32)
288 VUserLog(
"Error: BitsPerPixel=%lu isn't supported yet. Please use 32 bits per pixel, and https://vuo.org/contact us if you'd like support for other bit depths.", CGImageGetBitsPerPixel(cgimage));
292 unsigned long width = CGImageGetWidth(cgimage);
293 unsigned long height = CGImageGetHeight(cgimage);
294 if (CGImageGetBytesPerRow(cgimage) != width*4)
296 VUserLog(
"Error: BytesPerRow must be width*4. https://vuo.org/contact us if you'd like support for inexact strides.");
309 CGDataProviderRef provider = CGImageGetDataProvider(cgimage);
310 CFDataRef data = CGDataProviderCopyData(provider);
312 char *bitmapData = (
char *)CFDataGetBytePtr(data);
313 int bytesPerRow = width*4;
314 char *flippedBitmapData = (
char *)malloc(bytesPerRow*height);
317 for (
unsigned long y = 0; y < height; ++y)
318 memcpy(flippedBitmapData + bytesPerRow * (height - y - 1), bitmapData + bytesPerRow * y, bytesPerRow);
330 if (type == CVPixelBufferGetTypeID())
332 CVPixelBufferRef cvpb = (CVPixelBufferRef)value;
334 if (CVPixelBufferIsPlanar(cvpb))
336 VUserLog(
"Error: Planar buffers aren't supported yet. Please use chunky buffers, and https://vuo.org/contact us if you'd like support for planar buffers.");
340 if (CVPixelBufferGetPixelFormatType(cvpb) != kCVPixelFormatType_32BGRA)
342 unsigned long pf = CVPixelBufferGetPixelFormatType(cvpb);
343 VUserLog(
"Error: Pixel format %lu isn't supported yet. Please use kCVPixelFormatType_32BGRA, and https://vuo.org/contact us if you'd like support for other pixel formats.", pf);
347 unsigned long width = CVPixelBufferGetWidth(cvpb);
348 unsigned long height = CVPixelBufferGetHeight(cvpb);
349 if (CVPixelBufferGetBytesPerRow(cvpb) != width*4)
351 VUserLog(
"Error: BytesPerRow must be width*4. https://vuo.org/contact us if you'd like support for inexact strides.");
355 CVReturn ret = CVPixelBufferLockBaseAddress(cvpb, kCVPixelBufferLock_ReadOnly);
356 if (ret != kCVReturnSuccess)
358 VUserLog(
"CVPixelBufferLockBaseAddress() failed: %d", ret);
362 const unsigned char *pixels = (
const unsigned char *)CVPixelBufferGetBaseAddress(cvpb);
365 VUserLog(
"Error: CVPixelBufferGetBaseAddress() returned NULL.");
369 CVPixelBufferRetain(cvpb);
373 ret = CVPixelBufferUnlockBaseAddress(cvpb, kCVPixelBufferLock_ReadOnly);
374 if (ret != kCVReturnSuccess)
376 VUserLog(
"CVPixelBufferUnlockBaseAddress() failed: %d", ret);
385 #pragma clang diagnostic push
386 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
387 if (type == CVOpenGLTextureGetTypeID())
389 CVOpenGLTextureRef cvgl = (CVOpenGLTextureRef)value;
391 GLuint name = CVOpenGLTextureGetName(cvgl);
394 VUserLog(
"Error: CVOpenGLTextureGetName() returned 0.");
398 GLfloat lowerLeft[2];
399 GLfloat lowerRight[2];
400 GLfloat upperRight[2];
401 GLfloat upperLeft[2];
402 CVOpenGLTextureGetCleanTexCoords(cvgl, lowerLeft, lowerRight, upperRight, upperLeft);
404 unsigned int width = abs((
int)(lowerRight[0] - lowerLeft[0]));
405 unsigned int height = abs((
int)(upperLeft[1] - lowerLeft[1]));
409 GLenum target = CVOpenGLTextureGetTarget(cvgl);
410 if (target == GL_TEXTURE_2D)
412 else if (target == GL_TEXTURE_RECTANGLE_ARB)
416 VUserLog(
"Error: GL texture target %d isn't supported yet. Please use GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE_ARB, and https://vuo.org/contact us if you'd like support for other targets.", target);
425 #pragma clang diagnostic pop
427 NSString *typeDescription = (NSString *)CFCopyTypeIDDescription(type);
428 VUserLog(
"Error: Unknown CFType '%s'", [typeDescription UTF8String]);
429 [typeDescription release];
433 VUserLog(
"Error: Unknown type '%s' for object '%s'", object_getClassName(value), [[value description] UTF8String]);
440 + (NSImage *)nsImageWithVuoImage:(
VuoImage)vi
446 unsigned int bytesPerRow = 4 * vi->pixelsWide;
447 NSBitmapImageRep *nbi = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
448 pixelsWide:vi->pixelsWide
449 pixelsHigh:vi->pixelsHigh
454 colorSpaceName:NSDeviceRGBColorSpace
455 bytesPerRow:bytesPerRow
461 unsigned char *bitmapData = [nbi bitmapData];
463 glBindTexture(GL_TEXTURE_2D, vi->glTextureName);
464 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmapData);
465 glBindTexture(GL_TEXTURE_2D, 0);
469 unsigned char *tmp = (
unsigned char *)malloc(bytesPerRow);
470 for (
unsigned long y = 0; y < vi->pixelsHigh / 2; ++y)
472 memcpy(tmp, bitmapData + bytesPerRow * y, bytesPerRow);
473 memcpy(bitmapData + bytesPerRow * y, bitmapData + bytesPerRow * (vi->pixelsHigh - y - 1), bytesPerRow);
474 memcpy(bitmapData + bytesPerRow * (vi->pixelsHigh - y - 1), tmp, bytesPerRow);
478 NSImage *ni = [[NSImage alloc] initWithSize:[nbi size]];
479 [ni addRepresentation:nbi];
481 return [ni autorelease];
494 char type = [
self objCType][0];
499 if (type ==
'f' || type ==
'd')
502 if (type ==
'c' || type ==
'i' || type ==
's' || type ==
'l' || type ==
'q'
503 || type ==
'C' || type ==
'I' || type ==
'S' || type ==
'L' || type ==
'Q')
506 VUserLog(
"Error: Unknown type '%s'", [
self objCType]);
531 CGFloat c[4] = {0,0,0,1};
532 NSColor *color = [
self colorUsingColorSpace:[NSColorSpace sRGBColorSpace]];
533 [color getComponents:c];
546 NSColorSpace *nscs = [[NSColorSpace alloc] initWithCGColorSpace:[
self colorSpace]];
547 NSColor *color = [NSColor colorWithColorSpace:nscs components:[
self components] count:[
self numberOfComponents]];
549 return [color vuoValue];
561 float scale = [
self recommendedLayerContentsScale:0];
562 unsigned int pixelsWide = [
self size].width * scale;
563 unsigned int pixelsHigh = [
self size].height * scale;
565 NSBitmapImageRep *nbir = [[NSBitmapImageRep alloc]
566 initWithBitmapDataPlanes: NULL
567 pixelsWide:pixelsWide
568 pixelsHigh:pixelsHigh
573 colorSpaceName:NSDeviceRGBColorSpace
574 bytesPerRow:pixelsWide*4
577 NSGraphicsContext *ngc = [NSGraphicsContext graphicsContextWithBitmapImageRep:nbir];
578 [NSGraphicsContext saveGraphicsState];
579 [NSGraphicsContext setCurrentContext:ngc];
580 [
self drawInRect:NSMakeRect(0,0,pixelsWide,pixelsHigh) fromRect:NSZeroRect operation:NSCompositingOperationSourceOver fraction:1 respectFlipped:YES hints:nil];
582 [NSGraphicsContext setCurrentContext:nil];
583 [NSGraphicsContext restoreGraphicsState];
600 unsigned char *bitmapData = [
self bitmapData];
601 unsigned long width = [
self size].width;
602 unsigned long height = [
self size].height;
603 unsigned long bytesPerRow = width * 4;
604 unsigned char *bitmapDataFlipped = (
unsigned char *)malloc(bytesPerRow * height);
605 for (
unsigned long y = 0; y < height; ++y)
606 for (
unsigned long x = 0; x < width; ++x)
609 bitmapDataFlipped[bytesPerRow * (height - y - 1) + x * 4 + 2] = bitmapData[bytesPerRow * y + x * 4 + 0];
610 bitmapDataFlipped[bytesPerRow * (height - y - 1) + x * 4 + 1] = bitmapData[bytesPerRow * y + x * 4 + 1];
611 bitmapDataFlipped[bytesPerRow * (height - y - 1) + x * 4 + 0] = bitmapData[bytesPerRow * y + x * 4 + 2];
612 bitmapDataFlipped[bytesPerRow * (height - y - 1) + x * 4 + 3] = bitmapData[bytesPerRow * y + x * 4 + 3];
631 NSPoint p = [
self pointValue];
644 double p[3] = {0,0,0};
645 [
self getBytes:p length:sizeof(double)*3];
659 for (
id item in
self)
662 json_object_array_add(arrayJson, itemJson);