title: Setting up custom CIColorCube filter in SKEffectNode
body: <p>I'm trying to create a SKEffectNode that will turn transparent any green pixel over a black background. For testing purposes while I figure this stuff out, I want to make sure that the following code will not turn anything transparent within the subtree of the SKEffectNode. The following code actually prevents the child from being drawn and it spits up the following error:</p>
  
  <p><code>CIColorCube inputCubeData is not of the expected length.</code></p>
  
  <p>That's the method that creates the <code>SKEffectNode</code></p>
  
  <pre><code>- (SKEffectNode *) newVeil
  {
      SKEffectNode *node = [[SKEffectNode alloc] init];
  
      node.shouldEnableEffects = YES;
      node.filter = [self createFilter];
  
      SKSpriteNode *darkness = [SKSpriteNode spriteNodeWithColor:[UIColor blackColor] size:self.view.frame.size];
      node.position = self.view.center;
      [node addChild:darkness];
  
      return node;
  }
  </code></pre>
  
  <p>That's how I setup the filter (most, or dare I say all of this code is in <a href="https://developer.apple.com/library/ios/documentation/graphicsimaging/reference/CoreImageFilterReference/Reference/reference.html#//apple_ref/doc/filter/ci/CIColorCube" rel="nofollow" title="Apple's documentation">Apple's dev documents</a>).</p>
  
  <pre><code>- (CIFilter *) createFilter
  {
      // Allocate memory
      const unsigned int size = 64;
      float *cubeData = (float *)malloc (size * size * size * sizeof (float) * 4);
      float *c = cubeData;
      rgb rgbInput;
      hsv hsvOutput;
  
      // Populate cube with a simple gradient going from 0 to 1
      for (int z = 0; z &lt; size; z++){
          rgbInput.b = ((double)z)/(size-1); // Blue value
          for (int y = 0; y &lt; size; y++){
              rgbInput.g = ((double)y)/(size-1); // Green value
              for (int x = 0; x &lt; size; x ++){
                  rgbInput.r = ((double)x)/(size-1); // Red value
                  // Convert RGB to HSV
                  // You can find publicly available rgbToHSV functions on the Internet
                  hsvOutput = rgb2hsv(rgbInput);
                  // Use the hue value to determine which to make transparent
                  // The minimum and maximum hue angle depends on
                  // the color you want to remove
                  float alpha = (hsvOutput.h &gt; 120 &amp;&amp; hsvOutput.h &lt; 100) ? 0.0f: 1.0f;
                  // Calculate premultiplied alpha values for the cube
                  c[0] = rgbInput.b * alpha;
                  c[1] = rgbInput.g * alpha;
                  c[2] = rgbInput.r * alpha;
                  c[3] = alpha;
                  c += 4; // advance our pointer into memory for the next color value
              }
          }
      }
      // Create memory with the cube data
      NSData *data = [NSData dataWithBytesNoCopy:cubeData
                                          length:size
                                    freeWhenDone:YES];
  
      CIFilter *colorCube = [CIFilter filterWithName:@"CIColorCube"];
      [colorCube setValue:@(size) forKey:@"inputCubeDimension"];
      // Set data for cube
      [colorCube setValue:data forKey:@"inputCubeData"];
  
      return colorCube;
  }
  </code></pre>
  
  <p>I just can't spot the problem. Not a whole lot of experience with CoreImage. Anyone?</p>
  
  <p><strong>Update 1</strong></p>
  
  <p>I tried exporting the whole CIFilter into it's own class.</p>
  
  <pre><code>//  PMColorCube.h
  
  #import &lt;CoreImage/CoreImage.h&gt;
  
  @interface PMColorCube : CIFilter{
      CIImage *inputImage;
  }
  @property (retain, nonatomic) CIImage *inputImage;
  @end
  
  
  
  //  PMColorCube.m
  
  #import "PMColorCube.h"
  
  typedef struct {
      double r;       // percent
      double g;       // percent
      double b;       // percent
  } rgb;
  
  typedef struct {
      double h;       // angle in degrees
      double s;       // percent
      double v;       // percent
  } hsv;
  
  static hsv      rgb2hsv(rgb in);
  
  @implementation PMColorCube
  @synthesize inputImage;
  
  hsv rgb2hsv(rgb in)
  {
      hsv         out;
      double      min, max, delta;
  
      min = in.r &lt; in.g ? in.r : in.g;
      min = min  &lt; in.b ? min  : in.b;
  
      max = in.r &gt; in.g ? in.r : in.g;
      max = max  &gt; in.b ? max  : in.b;
  
      out.v = max;                                // v
      delta = max - min;
      if( max &gt; 0.0 ) {
          out.s = (delta / max);                  // s
      } else {
          // r = g = b = 0                        // s = 0, v is undefined
          out.s = 0.0;
          out.h = NAN;                            // its now undefined
          return out;
      }
      if( in.r &gt;= max )                           // &gt; is bogus, just keeps compilor happy
          out.h = ( in.g - in.b ) / delta;        // between yellow &amp; magenta
      else
          if( in.g &gt;= max )
              out.h = 2.0 + ( in.b - in.r ) / delta;  // between cyan &amp; yellow
          else
              out.h = 4.0 + ( in.r - in.g ) / delta;  // between magenta &amp; cyan
  
      out.h *= 60.0;                              // degrees
  
      if( out.h &lt; 0.0 )
          out.h += 360.0;
  
      return out;
  }
  
  - (CIImage *) outputImage
  {
      const unsigned int size = 64;
      float *cubeData = (float *)malloc (size * size * size * sizeof (float) * 4);
      float *c = cubeData;
      rgb rgbInput;
      hsv hsvOutput;
  
      // Populate cube with a simple gradient going from 0 to 1
      for (int z = 0; z &lt; size; z++){
          rgbInput.b = ((double)z)/(size-1); // Blue value
          for (int y = 0; y &lt; size; y++){
              rgbInput.g = ((double)y)/(size-1); // Green value
              for (int x = 0; x &lt; size; x ++){
                  rgbInput.r = ((double)x)/(size-1); // Red value
                  // Convert RGB to HSV
                  // You can find publicly available rgbToHSV functions on the Internet
                  hsvOutput = rgb2hsv(rgbInput);
                  // Use the hue value to determine which to make transparent
                  // The minimum and maximum hue angle depends on
                  // the color you want to remove
                  float alpha = (hsvOutput.h &gt; 120 &amp;&amp; hsvOutput.h &lt; 100) ? 0.0f: 1.0f;
                  // Calculate premultiplied alpha values for the cube
                  c[0] = rgbInput.b * alpha;
                  c[1] = rgbInput.g * alpha;
                  c[2] = rgbInput.r * alpha;
                  c[3] = alpha;
                  c += 4; // advance our pointer into memory for the next color value
              }
          }
      }
      // Create memory with the cube data
      NSData *data = [NSData dataWithBytesNoCopy:cubeData
                                          length:size
                                    freeWhenDone:YES];
  
      CIFilter *colorCube = [CIFilter filterWithName:@"CIColorCube"];
      [colorCube setValue:@(size) forKey:@"inputCubeDimension"];
      // Set data for cube
      [colorCube setValue:data forKey:@"inputCubeData"];
  
      [colorCube setValue:self.inputImage forKey:kCIInputImageKey];
      CIImage *result = [colorCube valueForKey:kCIOutputImageKey];
  
      return result;
  }
  @end
  </code></pre>
  
  <p>I still have the same error during run time</p>