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 if (type == CVOpenGLTextureGetTypeID())
387 CVOpenGLTextureRef cvgl = (CVOpenGLTextureRef)value;
389 GLuint name = CVOpenGLTextureGetName(cvgl);
392 VUserLog(
"Error: CVOpenGLTextureGetName() returned 0.");
396 GLfloat lowerLeft[2];
397 GLfloat lowerRight[2];
398 GLfloat upperRight[2];
399 GLfloat upperLeft[2];
400 CVOpenGLTextureGetCleanTexCoords(cvgl, lowerLeft, lowerRight, upperRight, upperLeft);
402 unsigned int width = abs((
int)(lowerRight[0] - lowerLeft[0]));
403 unsigned int height = abs((
int)(upperLeft[1] - lowerLeft[1]));
407 GLenum target = CVOpenGLTextureGetTarget(cvgl);
408 if (target == GL_TEXTURE_2D)
410 else if (target == GL_TEXTURE_RECTANGLE_ARB)
414 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);
424 NSString *typeDescription = (NSString *)CFCopyTypeIDDescription(type);
425 VUserLog(
"Error: Unknown CFType '%s'", [typeDescription UTF8String]);
426 [typeDescription release];
430 VUserLog(
"Error: Unknown type '%s' for object '%s'", object_getClassName(value), [[value description] UTF8String]);
437 + (NSImage *)nsImageWithVuoImage:(
VuoImage)vi
443 unsigned int bytesPerRow = 4 * vi->pixelsWide;
444 NSBitmapImageRep *nbi = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
445 pixelsWide:vi->pixelsWide
446 pixelsHigh:vi->pixelsHigh
451 colorSpaceName:NSDeviceRGBColorSpace
452 bytesPerRow:bytesPerRow
458 unsigned char *bitmapData = [nbi bitmapData];
460 glBindTexture(GL_TEXTURE_2D, vi->glTextureName);
461 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmapData);
462 glBindTexture(GL_TEXTURE_2D, 0);
466 unsigned char *tmp = (
unsigned char *)malloc(bytesPerRow);
467 for (
unsigned long y = 0; y < vi->pixelsHigh / 2; ++y)
469 memcpy(tmp, bitmapData + bytesPerRow * y, bytesPerRow);
470 memcpy(bitmapData + bytesPerRow * y, bitmapData + bytesPerRow * (vi->pixelsHigh - y - 1), bytesPerRow);
471 memcpy(bitmapData + bytesPerRow * (vi->pixelsHigh - y - 1), tmp, bytesPerRow);
475 NSImage *ni = [[NSImage alloc] initWithSize:[nbi size]];
476 [ni addRepresentation:nbi];
478 return [ni autorelease];
491 char type = [
self objCType][0];
496 if (type ==
'f' || type ==
'd')
499 if (type ==
'c' || type ==
'i' || type ==
's' || type ==
'l' || type ==
'q'
500 || type ==
'C' || type ==
'I' || type ==
'S' || type ==
'L' || type ==
'Q')
503 VUserLog(
"Error: Unknown type '%s'", [
self objCType]);
528 CGFloat c[4] = {0,0,0,1};
529 NSColor *color = [
self colorUsingColorSpace:[NSColorSpace sRGBColorSpace]];
530 [color getComponents:c];
543 NSColorSpace *nscs = [[NSColorSpace alloc] initWithCGColorSpace:[
self colorSpace]];
544 NSColor *color = [NSColor colorWithColorSpace:nscs components:[
self components] count:[
self numberOfComponents]];
546 return [color vuoValue];
558 float scale = [
self recommendedLayerContentsScale:0];
559 unsigned int pixelsWide = [
self size].width * scale;
560 unsigned int pixelsHigh = [
self size].height * scale;
562 NSBitmapImageRep *nbir = [[NSBitmapImageRep alloc]
563 initWithBitmapDataPlanes: NULL
564 pixelsWide:pixelsWide
565 pixelsHigh:pixelsHigh
570 colorSpaceName:NSDeviceRGBColorSpace
571 bytesPerRow:pixelsWide*4
574 NSGraphicsContext *ngc = [NSGraphicsContext graphicsContextWithBitmapImageRep:nbir];
575 [NSGraphicsContext saveGraphicsState];
576 [NSGraphicsContext setCurrentContext:ngc];
577 [
self drawInRect:NSMakeRect(0,0,pixelsWide,pixelsHigh) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1 respectFlipped:YES hints:nil];
579 [NSGraphicsContext setCurrentContext:nil];
580 [NSGraphicsContext restoreGraphicsState];
597 unsigned char *bitmapData = [
self bitmapData];
598 unsigned long width = [
self size].width;
599 unsigned long height = [
self size].height;
600 unsigned long bytesPerRow = width * 4;
601 unsigned char *bitmapDataFlipped = (
unsigned char *)malloc(bytesPerRow * height);
602 for (
unsigned long y = 0; y < height; ++y)
603 for (
unsigned long x = 0; x < width; ++x)
606 bitmapDataFlipped[bytesPerRow * (height - y - 1) + x * 4 + 2] = bitmapData[bytesPerRow * y + x * 4 + 0];
607 bitmapDataFlipped[bytesPerRow * (height - y - 1) + x * 4 + 1] = bitmapData[bytesPerRow * y + x * 4 + 1];
608 bitmapDataFlipped[bytesPerRow * (height - y - 1) + x * 4 + 0] = bitmapData[bytesPerRow * y + x * 4 + 2];
609 bitmapDataFlipped[bytesPerRow * (height - y - 1) + x * 4 + 3] = bitmapData[bytesPerRow * y + x * 4 + 3];
628 NSPoint p = [
self pointValue];
641 double p[3] = {0,0,0};
642 [
self getBytes:p length:sizeof(double)*3];
656 for (
id item in
self)
659 json_object_array_add(arrayJson, itemJson);