Vuo  2.3.2
VuoColorspace.m
Go to the documentation of this file.
1 
10 #include "module.h"
11 
12 #include "VuoColorspace.h"
13 
14 #ifdef VUO_COMPILER
16  "title" : "VuoColorspace",
17 });
18 #endif
19 
20 #include "VuoMacOSSDKWorkaround.h"
21 #import <AppKit/AppKit.h>
22 
29 {
30  if (colorspace == 0)
31  // http://www.rapidtables.com/convert/color/cmyk-to-rgb.htm
32  return VuoColor_makeWithRGBA(
33  (1. - c) * (1. - k),
34  (1. - m) * (1. - k),
35  (1. - y) * (1. - k),
36  a);
37  else
38  {
39  CGFloat components[5] = { c, m, y, k, a };
40  NSColor *inputColor = [NSColor colorWithColorSpace:NSColorSpace.genericCMYKColorSpace components:components count:5];
41  NSColor *outputColor = [inputColor colorUsingColorSpace:NSColorSpace.sRGBColorSpace];
42  return VuoColor_makeWithRGBA(outputColor.redComponent, outputColor.greenComponent, outputColor.blueComponent, outputColor.alphaComponent);
43  }
44 }
45 
51 void VuoColorspace_getCMYKA(VuoColor color, int colorspace, VuoReal *c, VuoReal *m, VuoReal *y, VuoReal *k, VuoReal *a)
52 {
53  if (colorspace == 0)
54  {
55  // http://www.rapidtables.com/convert/color/rgb-to-cmyk.htm
56 
57  double r = color.r,
58  g = color.g,
59  b = color.b;
60 
61  *k = 1. - MAX(MAX(r, g), b);
62  if (VuoReal_areEqual(*k, 1))
63  *c = *m = *y = 0;
64  else
65  {
66  *c = (1. - r - *k) / (1. - *k);
67  *m = (1. - g - *k) / (1. - *k);
68  *y = (1. - b - *k) / (1. - *k);
69  }
70  *a = color.a;
71  }
72  else
73  {
74  CGFloat components[4] = { color.r, color.g, color.b, color.a };
75  NSColor *inputColor = [NSColor colorWithColorSpace:NSColorSpace.sRGBColorSpace components:components count:4];
76  NSColor *outputColor = [inputColor colorUsingColorSpace:NSColorSpace.genericCMYKColorSpace];
77  *c = outputColor.cyanComponent;
78  *m = outputColor.magentaComponent;
79  *y = outputColor.yellowComponent;
80  *k = outputColor.blackComponent;
81  *a = outputColor.alphaComponent;
82  }
83 }
84 
85 static NSColorSpace *_VuoColorspace_colorspaceForInteger(VuoInteger colorspace)
86 {
87  if (colorspace == 0)
88  return [NSColorSpace.sRGBColorSpace retain];
89  else if (colorspace == 1)
90  return [NSColorSpace.adobeRGB1998ColorSpace retain];
91  else if (colorspace == 2)
92  return [NSColorSpace.genericRGBColorSpace retain];
93  else if (colorspace == 3)
94  return [NSColorSpace.genericCMYKColorSpace retain];
95  else if (colorspace == 4)
96  return [[NSColorSpace alloc] initWithICCProfileData:[NSData dataWithContentsOfFile:@"/System/Library/ColorSync/Profiles/Generic Lab Profile.icc"]];
97  else if (colorspace == 5)
98  return [[NSColorSpace alloc] initWithICCProfileData:[NSData dataWithContentsOfFile:@"/System/Library/ColorSync/Profiles/Generic XYZ Profile.icc"]];
99 
100  return nil;
101 }
102 
103 static NSColorSpace *_VuoColorspace_colorspaceForData(VuoData colorspace)
104 {
105  if (!colorspace.data || colorspace.size <= 0)
106  return nil;
107 
108  NSData *data = [NSData dataWithBytesNoCopy:colorspace.data length:colorspace.size freeWhenDone:NO];
109  if (!data)
110  return nil;
111 
112  return [[NSColorSpace alloc] initWithICCProfileData:data];
113 }
114 
115 static VuoColor _VuoColorspace_convertFromICC(NSColorSpace *cs, VuoList_VuoReal components)
116 {
117  if (!cs)
118  {
119  VUserLog("Error: Couldn't load colorspace.");
120  return VuoColor_makeWithRGBA(0,0,0,0);
121  }
122 
123  unsigned long providedComponentCount = VuoListGetCount_VuoReal(components);
124  unsigned long allowedComponentCount = cs.numberOfColorComponents + 1;
125  CGFloat cfComponents[allowedComponentCount];
126  for (int i = 0; i < allowedComponentCount - 1; ++i)
127  cfComponents[i] = 0;
128  cfComponents[allowedComponentCount - 1] = 1; // Alpha
129  for (int i = 0; i < MIN(providedComponentCount, allowedComponentCount); ++i)
130  cfComponents[i] = VuoListGetValue_VuoReal(components, i + 1);
131 
132  NSColor *inputColor = [NSColor colorWithColorSpace:cs components:cfComponents count:allowedComponentCount];
133  [cs release];
134  NSColor *outputColor = [inputColor colorUsingColorSpace:NSColorSpace.sRGBColorSpace];
135  return VuoColor_makeWithRGBA(outputColor.redComponent, outputColor.greenComponent, outputColor.blueComponent, outputColor.alphaComponent);
136 }
137 
144 {
145  return _VuoColorspace_convertFromICC(_VuoColorspace_colorspaceForInteger(colorspace), components);
146 }
147 
153 {
154  return _VuoColorspace_convertFromICC(_VuoColorspace_colorspaceForData(colorspace), components);
155 }
156 
157 static VuoList_VuoReal _VuoColorspace_convertToICC(NSColorSpace *cs, VuoColor color)
158 {
159  if (!cs)
160  {
161  VUserLog("Error: Couldn't load colorspace.");
162  return NULL;
163  }
164 
165  NSColor *inputColor = [NSColor colorWithSRGBRed:color.r green:color.g blue:color.b alpha:color.a];
166  NSColor *outputColor = [inputColor colorUsingColorSpace:cs];
167  [cs release];
168 
169  unsigned long componentCount = outputColor.numberOfComponents;
170  CGFloat outputComponents[componentCount];
171  [outputColor getComponents:outputComponents];
172 
173  VuoList_VuoReal outputList = VuoListCreate_VuoReal();
174  for (int i = 0; i < componentCount; ++i)
175  VuoListAppendValue_VuoReal(outputList, outputComponents[i]);
176 
177  return outputList;
178 }
179 
186 {
187  return _VuoColorspace_convertToICC(_VuoColorspace_colorspaceForInteger(colorspace), color);
188 }
189 
194 {
195  return _VuoColorspace_convertToICC(_VuoColorspace_colorspaceForData(colorspace), color);
196 }