tags:

views:

204

answers:

2

Hi all,

I have a raw image buffer in the RGB format. I need to draw it to CGContext so that I get a new buffer of the format ARGB. I accomplish this in the following way:

Create a data provider out of raw buffer using CGDataProviderCreateWithData and then create image out of the data provider with the api: CGImageCreate.

Now if I write this image back to the CGBitmapContext using CGContextImageDraw.

Instead of creating an intermediate image, is there any way of writing the buffer directly to CGContext so that I can avoid the image creation phase?

Thanks

A: 

If you are using a CGBitmapContext then you can get a pointer to the bitmap buffer using the CGBitmapContextGetData() function. You can then write your data directly to the buffer.

Rob Keniger
Yup, I am using CGBitmapContext, but my requirement is exactly the opposite. I have a RGB buffer which I want to convert it to RGBA / ARGB buffer.
Raj
In that case I don't think you have much option. You'll need to create a `CGImageRef` from your RGB data, and then draw it in an ARGB `CGBitmapContext`. Is there a reason you don't want to use a CGImage?
Rob Keniger
Ya, I need a new buffer from existing buffer, so is it necessary that I create an intermediate CGImage and convert it back (by using CGBitmapContext)?
Raj
+2  A: 

If all you want is to take RGB data with no alpha component and turn it into ARGB data with full opacity (alpha = 1.0 at all points), why not just copy the data yourself into a new buffer?

// assuming 24-bit RGB (1 byte per color component)
unsigned char *rgb = /* ... */;
size_t rgb_bytes = /* ... */;
const size_t bpp_rgb = 3;  // bytes per pixel - rgb
const size_t bpp_argb = 4;  // bytes per pixel - argb
const size_t npixels = rgb_bytes / bpp_rgb;
unsigned char *argb = malloc(npixels * bpp_argb);
for (size_t i = 0; i < npixels; ++i) {
    const size_t argbi = bpp_argb * i;
    const size_t rgbi = bpp_rgb * i;
    argb[argbi] = 0xFF;  // alpha - full opacity
    argb[argbi + 1] = rgb[rgbi];  // r
    argb[argbi + 2] = rgb[rgbi + 1];  // g
    argb[argbi + 3] = rgb[rgbi + 2];  // b
}
Jeremy W. Sherman
Its a good suggestion Jeremy, I have already tried it but it turns out to be too slow. I was just wondering if there are any efficient ways to achieve this. Seems that the only possible way is just as I am doing right now and the one Rob suggested. Create an image and draw it back to the context.
Raj
Be sure to test speed under the release configuration, with all compiler optimizations applied, rather than the debug configuration. If it's still too slow, you could try (in likely order of difficulty): unrolling the loop by hand; reading and writing words rather than bytes; using vector instructions; offloading the work to the GPU.
Jeremy W. Sherman