Vuo  2.1.0
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 
22 #ifndef NS_RETURNS_INNER_POINTER
23 #define NS_RETURNS_INNER_POINTER
24 #endif
25 #import <AppKit/AppKit.h>
26 #undef NS_RETURNS_INNER_POINTER
27 
28 
35 {
36  if (colorspace == 0)
37  // http://www.rapidtables.com/convert/color/cmyk-to-rgb.htm
38  return VuoColor_makeWithRGBA(
39  (1. - c) * (1. - k),
40  (1. - m) * (1. - k),
41  (1. - y) * (1. - k),
42  a);
43  else
44  {
45  CGFloat components[5] = { c, m, y, k, a };
46  NSColor *inputColor = [NSColor colorWithColorSpace:NSColorSpace.genericCMYKColorSpace components:components count:5];
47  NSColor *outputColor = [inputColor colorUsingColorSpace:NSColorSpace.sRGBColorSpace];
48  return VuoColor_makeWithRGBA(outputColor.redComponent, outputColor.greenComponent, outputColor.blueComponent, outputColor.alphaComponent);
49  }
50 }
51 
57 void VuoColorspace_getCMYKA(VuoColor color, int colorspace, VuoReal *c, VuoReal *m, VuoReal *y, VuoReal *k, VuoReal *a)
58 {
59  if (colorspace == 0)
60  {
61  // http://www.rapidtables.com/convert/color/rgb-to-cmyk.htm
62 
63  double r = color.r,
64  g = color.g,
65  b = color.b;
66 
67  *k = 1. - MAX(MAX(r, g), b);
68  if (VuoReal_areEqual(*k, 1))
69  *c = *m = *y = 0;
70  else
71  {
72  *c = (1. - r - *k) / (1. - *k);
73  *m = (1. - g - *k) / (1. - *k);
74  *y = (1. - b - *k) / (1. - *k);
75  }
76  *a = color.a;
77  }
78  else
79  {
80  CGFloat components[4] = { color.r, color.g, color.b, color.a };
81  NSColor *inputColor = [NSColor colorWithColorSpace:NSColorSpace.sRGBColorSpace components:components count:4];
82  NSColor *outputColor = [inputColor colorUsingColorSpace:NSColorSpace.genericCMYKColorSpace];
83  *c = outputColor.cyanComponent;
84  *m = outputColor.magentaComponent;
85  *y = outputColor.yellowComponent;
86  *k = outputColor.blackComponent;
87  *a = outputColor.alphaComponent;
88  }
89 }
90 
91 static NSColorSpace *_VuoColorspace_colorspaceForInteger(VuoInteger colorspace)
92 {
93  if (colorspace == 0)
94  return [NSColorSpace.sRGBColorSpace retain];
95  else if (colorspace == 1)
96  return [NSColorSpace.adobeRGB1998ColorSpace retain];
97  else if (colorspace == 2)
98  return [NSColorSpace.genericRGBColorSpace retain];
99  else if (colorspace == 3)
100  return [NSColorSpace.genericCMYKColorSpace retain];
101  else if (colorspace == 4)
102  return [[NSColorSpace alloc] initWithICCProfileData:[NSData dataWithContentsOfFile:@"/System/Library/ColorSync/Profiles/Generic Lab Profile.icc"]];
103  else if (colorspace == 5)
104  return [[NSColorSpace alloc] initWithICCProfileData:[NSData dataWithContentsOfFile:@"/System/Library/ColorSync/Profiles/Generic XYZ Profile.icc"]];
105 
106  return nil;
107 }
108 
109 static NSColorSpace *_VuoColorspace_colorspaceForData(VuoData colorspace)
110 {
111  if (!colorspace.data || colorspace.size <= 0)
112  return nil;
113 
114  NSData *data = [NSData dataWithBytesNoCopy:colorspace.data length:colorspace.size freeWhenDone:NO];
115  if (!data)
116  return nil;
117 
118  return [[NSColorSpace alloc] initWithICCProfileData:data];
119 }
120 
121 static VuoColor _VuoColorspace_convertFromICC(NSColorSpace *cs, VuoList_VuoReal components)
122 {
123  if (!cs)
124  {
125  VUserLog("Error: Couldn't load colorspace.");
126  return VuoColor_makeWithRGBA(0,0,0,0);
127  }
128 
129  unsigned long providedComponentCount = VuoListGetCount_VuoReal(components);
130  unsigned long allowedComponentCount = cs.numberOfColorComponents + 1;
131  CGFloat cfComponents[allowedComponentCount];
132  for (int i = 0; i < allowedComponentCount - 1; ++i)
133  cfComponents[i] = 0;
134  cfComponents[allowedComponentCount - 1] = 1; // Alpha
135  for (int i = 0; i < MIN(providedComponentCount, allowedComponentCount); ++i)
136  cfComponents[i] = VuoListGetValue_VuoReal(components, i + 1);
137 
138  NSColor *inputColor = [NSColor colorWithColorSpace:cs components:cfComponents count:allowedComponentCount];
139  [cs release];
140  NSColor *outputColor = [inputColor colorUsingColorSpace:NSColorSpace.sRGBColorSpace];
141  return VuoColor_makeWithRGBA(outputColor.redComponent, outputColor.greenComponent, outputColor.blueComponent, outputColor.alphaComponent);
142 }
143 
150 {
151  return _VuoColorspace_convertFromICC(_VuoColorspace_colorspaceForInteger(colorspace), components);
152 }
153 
159 {
160  return _VuoColorspace_convertFromICC(_VuoColorspace_colorspaceForData(colorspace), components);
161 }
162 
163 static VuoList_VuoReal _VuoColorspace_convertToICC(NSColorSpace *cs, VuoColor color)
164 {
165  if (!cs)
166  {
167  VUserLog("Error: Couldn't load colorspace.");
168  return NULL;
169  }
170 
171  NSColor *inputColor = [NSColor colorWithSRGBRed:color.r green:color.g blue:color.b alpha:color.a];
172  NSColor *outputColor = [inputColor colorUsingColorSpace:cs];
173  [cs release];
174 
175  unsigned long componentCount = outputColor.numberOfComponents;
176  CGFloat outputComponents[componentCount];
177  [outputColor getComponents:outputComponents];
178 
179  VuoList_VuoReal outputList = VuoListCreate_VuoReal();
180  for (int i = 0; i < componentCount; ++i)
181  VuoListAppendValue_VuoReal(outputList, outputComponents[i]);
182 
183  return outputList;
184 }
185 
192 {
193  return _VuoColorspace_convertToICC(_VuoColorspace_colorspaceForInteger(colorspace), color);
194 }
195 
200 {
201  return _VuoColorspace_convertToICC(_VuoColorspace_colorspaceForData(colorspace), color);
202 }