Does anyone know what the limitations are on image size with custom CIFilters? I've created a filter that performs as expected when the images are up to 2 mega pixels but then produce very strange results when the images are larger. I've tested this both in my cocoa app as well as in quartz composer. The filter I've developed is a geometry-type distortion filter that (I think) requires an ROI and a DOD that spans the entire input image. I've created this filter for remapping panoramic images so I'd like this to work on very large (50-100 mega pixel) images.
As a simple test the consider the following CIFilter (can be used in Quartz Composer) that simply translates the image so that the lower-left corner of the images is translated to the center (I know this could be done with an affine transform but I need to perform such an operation in a more complex filter). This filter works as expected when the image is 2000x1000 but produces odd results when the input image is 4000x2000 pixels. The problem is that either the translation does not move the corner to the center exactly or that the image output is gone entirely. I've noticed other odd problems with more complicated filters on large images but I think this simple filter illustrates my issue and can be replicated in Quartz Composer.
kernel vec4 equidistantProjection(sampler src, __color color) { vec2 coordinate = samplerCoord(src); vec2 result; vec4 outputImage;
result.x = (coordinate.x - samplerSize(src).x / 2.0);
result.y = (coordinate.y - samplerSize(src).y / 2.0);
outputImage = unpremultiply(sample(src,result));
return premultiply(outputImage);
}
The same odd behavior appears when using the working coordinates instead of the sampler coordinates but in this case the error occurs for images of size 2000x1000 but works fine for images of size 1000x500
kernel vec4 equidistantProjection(sampler src, __color color, vec2 destinationDimensions) { vec2 coordinate = destCoord(); vec2 result; vec4 outputImage;
result.x = (coordinate.x - destinationDimensions.x / 2.0);
result.y = (coordinate.y - destinationDimensions.y / 2.0);
outputImage = unpremultiply(sample(src,result));
outputImage = unpremultiply(sample(src,samplerTransform(src, result)));
return premultiply(outputImage);
}
For reference I have added to the Objective-C portion of my filter's - (CIImage *)outputImage method the following to set the DOD to be the entire input image.
(CIImage *)outputImage { CISampler *src = [CISampler samplerWithImage: inputImage];
NSArray * outputExtent = [NSArray arrayWithObjects: [NSNumber numberWithInt:0], [NSNumber numberWithInt:0], [NSNumber numberWithFloat:[inputImage extent].size.width], [NSNumber numberWithFloat:[inputImage extent].size.height],nil];
return [self apply: filterKernel, src, inputColor, zoom, viewBounds, inputOrigin, kCIApplyOptionDefinition, [src definition], kCIApplyOptionExtent, outputExtent, nil];
}
Additionally I added the following method to set the ROI which I call in my - (id)init method with this: [filterKernel setROISelector:@selector(regionOf:destRect:userInfo:)];
(CGRect) regionOf:(int)samplerIndex destRect:(CGRect)r userInfo:obj {
return r; }
Any help or advice on this issue would be greatly appreciated. I'm sure that CIFilters can work with larger images as I've used the CIBumpDistortion with greater than 50 megapixel images so I must be doing something wrong. Any ideas?