samuelschaefer samuelschaefer - 4 months ago 16
Objective-C Question

CFDataRef and Pixel Data for iPhone Programming

I am trying to access the raw pixels of an image, but I keep running into a problem that got me really stuck. I am pretty new to iPhone programming so it might be something really simple...

Here is the class I have, it uses a

CGImageRef
from an image and looks at the individual pixels. Here is my code

The header file:

#import <QuartzCore/QuartzCore.h>
#import <QuartzCore/QuartzCore.h>
#import <CoreImage/CoreImage.h>


@interface GraphingView : UIControl
{
@private
CAShapeLayer *shapeLayer;
CGImageRef pixelData;
}

@property(assign) CGImageRef pixelData;
@end


And my implementation file:

#import "GraphingView.h"
#import "iSpectrumViewController.h"

@implementation GraphingView

@synthesize pixelData;
- (void)awakeFromNib
{
// set up a rounded border
CALayer *layer = [self layer];

// clear the view's background color so that our background
// fits within the rounded border
CGColorRef backgroundColor = [self.backgroundColor CGColor];
self.backgroundColor = [UIColor clearColor];
layer.backgroundColor = backgroundColor;


shapeLayer = [CAShapeLayer layer];

[self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect
{

}

- (void)updateGraph
{
// This is where my problem is:
// Whenever the next line is executed the application stops working. It works fine in the setPixelData
// down below.
CFDataRef pixelRef = CGDataProviderCopyData(CGImageGetDataProvider(pixelData));
CFIndex byteSize = CFDataGetLength(pixelRef);
int intByteSize = (int) byteSize;
NSLog(@"Number of Bytes contained %i",intByteSize);

//Then get a pointer to the data so the information can be accessed
const UInt8 *pixelPtr = CFDataGetBytePtr(pixelRef);


// Do some drawing here using the data obtained from the image...

[shapeLayer setPath:path];
[shapeLayer setNeedsDisplay];
CFRelease(path);
}

-(void)setPixelData:(CGImageRef)pixelImage
{
//This code takes the CGImage from my image and copies it to the pixelData CGImageRef defined in the header file


//This gets the CFDataRef from the CGImage so the pixel information is available
CFDataRef PixelCopy = CGDataProviderCopyData(CGImageGetDataProvider(pixelImage));
CFIndex byteSize = CFDataGetLength(PixelCopy);
int intByteSize = (int) byteSize;
NSLog(@"Number of Bytes contained %i",intByteSize);

pixelData = CGImageCreateCopy(pixelImage);
[self updateGraph];

}
@end


The problem I have is:

The function
setPixelData
gets the
CGImageRef
image and copies it to
pixelData
. Then, up in the
(void) updateGraph
method, I use the
CGImageRef pixelData
and create a
CFDataRef
to get the raw pixel data. However, there is something wrong. Because when I use the
CFDataGetLength
method using the
CFDataRef pixelRef
as input I get the
EXC_BAD_ACCESS
error when the program is run. What confuses me is that when I then put the same two lines of code in the
(void) setPixelData
function (shown in the code above) and comment out the code in
updateGraph
then the program runs perfectly fine.

Any ideas of what could be causing this error, and how to eliminate it?

Thanks,

Sam

Answer

Ah... I found it,

The reason it didn't work was because I had two setter methods (one of them is not shown in the code). That one always ran before the setPixelData function, so PixelData CGImageRef was never set, therefore, CFDataRef did not exist, giving the memory error.