CGDataProviderCreateDirect

It’s hard to find an example using CGDataProviderCreateDirect, so here’s a quick snippet:

static unsigned int* data; // used for manipulating pixel data directly

const void * getBytePointerCallback(void *info)
{
	return (void*)data;
}

@implementation SomeView

- (void)createImage
{
    CGDataProviderDirectCallbacks callbacks;
    callbacks.version = 0;
    callbacks.getBytePointer = getBytePointerCallback;
    callbacks.releaseBytePointer = NULL;
    callbacks.getBytesAtPosition = NULL;
    callbacks.releaseInfo = NULL;
    
    float w = self.layer.frame.size.width;
    float h = self.layer.frame.size.height;
    
    w *= [UIScreen mainScreen].scale;
    h *= [UIScreen mainScreen].scale;
    
    int numComponents = 4;
    uint dataLength = w * h * numComponents;
    
    data = malloc(dataLength * sizeof(uint)); // TODO: free
    
    uint r = 255;
    uint g = 0;
    uint b = 0;
    for(int i = 0; i < dataLength; ++i)
    {
        data[i] = 255 << 24 | b << 16 | g << 8 | r;
    }
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    
    CGDataProviderRef bitmapProvider = CGDataProviderCreateDirect(data,dataLength,&callbacks);

    CGImageRef bitmap = CGImageCreate(w,
                                      h,
                                      8,    // bits per component
                                      8*numComponents,  // total bits
                                      w*numComponents,  // bytes per row
                                      colorSpace,
                                      kCGBitmapByteOrderDefault,
                                      bitmapProvider,
                                      NULL,
                                      false,
                                      kCGRenderingIntentDefault);    
    
    self.layer.contents = (__bridge id)(bitmap);
    
    CGImageRelease(bitmap);
    CGDataProviderRelease(bitmapProvider);
    CGColorSpaceRelease(colorSpace);
}