How to access pixels of an NSBitmapImageRep?

I have an NSBitmapImageRep that is created like this:

NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] 
                              initWithBitmapDataPlanes:NULL
                                            pixelsWide:waveformSize.width
                                            pixelsHigh:waveformSize.height
                                         bitsPerSample:8
                                       samplesPerPixel:4
                                              hasAlpha:YES
                                              isPlanar:YES
                                        colorSpaceName:NSCalibratedRGBColorSpace
                                           bytesPerRow:0
                                          bitsPerPixel:0];

Now I want to access the pixel data so I get a pointer to the pixel planes using

unsigned char *bitmapData;
[imageRep getBitmapDataPlanes:&bitmapData];

According to the Documentation this returns a C array of five character pointers. But how can it do that? since the type of the argument is unsigned char **, it can only return an array of chars, but not an array of char pointers.

So, this leaves me wondering how to access the individual pixels. Do you have an idea how to do that?

(I know there is the method – setColor:atX:y:, but it seems to be pretty slow if invoked for every single pixel of a big bitmap.)

Answers


If you just want to iterate over the pixels, -bitmapData should be all you need.


According to the Documentation this returns a C array of five character pointers. But how can it do that? since the type of the argument is unsigned char **, it can only return an array of chars, but not an array of char pointers.

Incorrect. unsigned char ** is a pointer to at least one pointer to at least one unsigned char.

So, you're supposed to pass a pointer to an array of pointers—that is, a pointer to an array of arrays. Something like this:

unsigned char *buffers[5];
[bitmapImageRep getBitmapDataPlanes:buffers];

If the image rep is planar, then each element of buffers will be a pointer to a component plane; for RGB, buffers[0] is the red plane, buffers[1] is the green plane, buffers[2] is the blue plane, and buffers[3] is the alpha plane. Each plane is, of course, a buffer holding the values for that channel (as unsigned chars).

If the image rep is not planar, then you'll get only one element, which is the RGBA data.

Of particular note is this sentence from the documentation you linked to:

If there are less than five planes, the remaining pointers will be set to NULL.

This means that the code you show contains a buffer overflow: You're passing a pointer to storage for one pointer, but the image rep expects storage for no fewer than five, and it will give you five pointers and/or NULLs, so it will be writing beyond the end of the storage you gave it. This will smash your stack, crash your application, or both.


Need Your Help

Exit browser full screen mode when F11 is hit while Flash object is active?

javascript flash browser fullscreen

I have a 100% width and height flash object in my site. Activating and exiting browser full screen mode with F11 only works as long the user didn't click the Flash movie. And I doubt many users kno...