- (CGColorSpaceRef)getScreenColorspace
{	
	if (!_screenColorspace)
	{
		CMProfileRef systemProfile = NULL;
		OSStatus status = CMGetSystemProfile(&systemProfile);
		NSParameterAssert( noErr == status);
		_screenColorspace = CGColorSpaceCreateWithPlatformColorSpace(systemProfile);
		CMCloseProfile(systemProfile);
	}
	return _screenColorspace;
}


- (size_t)optimalRowBytesForWidth: (size_t)width bytesPerPixel: (size_t)bytesPerPixel
{
    size_t rowBytes = width * bytesPerPixel;
    
    //Widen rowBytes out to a integer multiple of 16 bytes
    rowBytes = (rowBytes + 15) & ~15;
    
    //Make sure we are not an even power of 2 wide. 
    //Will loop a few times for rowBytes <= 16.
    while( 0 == (rowBytes & (rowBytes - 1) ) )
        rowBytes += 16;
    
    return rowBytes;
}
    
    
- (UInt32 const *)createPremultipliedRGBA_8888_BitmapForCIImage: (CIImage *)image rowBytes: (size_t *)rowBytes
{
    NSParameterAssert( image != nil );
    NSParameterAssert( rowBytes != NULL );
    
    // - Get the geometry of the image
    
    CGRect extent = [image extent];
    CGRect zeroRect = {CGPointZero, extent.size};
    NSParameterAssert( CGRectIsInfinite(extent) == NO );
    size_t destWidth = (size_t)extent.size.width;
    size_t destHeight = (size_t)extent.size.height;
    
    // - Create contexts
    
    CGContextRef cgContext = NULL;
    CIContext *ciContext = nil;
    size_t bitsPerComponent = 8;
    size_t bytesPerRow = [self optimalRowBytesForWidth: destWidth bytesPerPixel: 4];
    CGColorSpaceRef colorspace = [self getScreenColorspace];
    CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault;
    
    UInt32 *bitmapData = malloc(bytesPerRow * destHeight);
    if (bitmapData)
    {
        cgContext = CGBitmapContextCreate(bitmapData, destWidth, destHeight, bitsPerComponent, bytesPerRow, colorspace, bitmapInfo);
        if (cgContext)
        {
            NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
                (id)colorspace,     kCIContextOutputColorSpace, 
                (id)colorspace,     kCIContextWorkingColorSpace, 
                nil];
            ciContext = [CIContext contextWithCGContext: cgContext options: options];
            if (ciContext)
                success = YES;
        }
    }
    NSParameterAssert( cgContext != NULL && ciContext != nil );

    // - Render the image into the contexts

    CGContextClearRect(cgContext, zeroRect);
    [ ciContext drawImage: image atPoint: CGPointZero fromRect: extent];
    CGContextFlush(cgContext);

    // - Get the geometry of the context
    
    *rowBytes = CGBitmapContextGetBytesPerRow(cgContext);
    CGContextRelease(cgContext);
    
    return bitmapData;
}