Question

I have a method that will add a filter to an image. This worked fine until a couple of months ago, now when I try to use this method the application will crash on the images buffer. I create the buffer and set it to the image's data, accessing the specific index later causes a bad access crash. I have looked for the past hour or two, and now I am convinced there is something im overlooking. I think something is being released that should not be. I am using the ios DP 4 preview of xcode, and I think this problem started with the update to the beta, but I am really not sure.

This is the line it crashes on located near the middle of the first for loop

    m_PixelBuf[index+2] = m_PixelBuf[index+2]/*aRed*/;

Normally it is set to aRed Which I have checked, and it should not go out of the buffers boundaries.

    -(void)contrastWithContrast:(float )contrast colorWithColor:(float )color{
    drawImage.image = original;
    UIImage * unfilteredImage2 = [[[UIImage alloc]initWithCGImage:drawImage.image.CGImage]    autorelease];
    CGImageRef inImage = unfilteredImage2.CGImage;         
    CGContextRef ctx;
    CFDataRef m_DataRef;
    m_DataRef = CGDataProviderCopyData(CGImageGetDataProvider(inImage));
    UInt8 * m_PixelBuf  = (UInt8 *) CFDataGetBytePtr(m_DataRef);
    int length = CFDataGetLength(m_DataRef);
    NSLog(@"Photo Length: %i",length);
    //////Contrast/////////////
    //NSLog(@"Contrast:%f",contrast);
    int aRed;
    int aGreen;
    int aBlue;
    for (int index = 0; index < length; index += 4){
    aRed = m_PixelBuf[index+2];
    aGreen = m_PixelBuf[index+1];
    aBlue = m_PixelBuf[index];

    aRed = (((aRed-128)*(contrast+100) )/100) + 128;
    if (aRed < 0) aRed = 0; if (aRed>255) aRed=255;
    m_PixelBuf[index+2] = m_PixelBuf[index+2]/*aRed*/;//Always crashes here

    aGreen = (((aGreen-128)*(contrast+100) )/100) + 128;
    if (aGreen < 0) aGreen = 0; if (aGreen>255) aGreen=255;
    m_PixelBuf[index+1] = aGreen;

    aBlue = (((aBlue-128)*(contrast+100) )/100) + 128;
    if (aBlue < 0) aBlue = 0; if (aBlue>255) aBlue=255;
    m_PixelBuf[index] = aBlue;
}
ctx = CGBitmapContextCreate(m_PixelBuf,
                            CGImageGetWidth( inImage ),  
                            CGImageGetHeight( inImage ),  
                            CGImageGetBitsPerComponent(inImage),
                            CGImageGetBytesPerRow(inImage ),  
                            CGImageGetColorSpace(inImage ),  
                            CGImageGetBitmapInfo(inImage) );
CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
UIImage* rawImage = [[UIImage alloc]initWithCGImage:imageRef];
drawImage.image = rawImage;

[rawImage release];
CGContextRelease(ctx); 
CFRelease(imageRef);
CFRelease(m_DataRef);

unfilteredImage2 = [[[UIImage alloc]initWithCGImage:drawImage.image.CGImage] autorelease];
inImage = unfilteredImage2.CGImage;         
m_DataRef = CGDataProviderCopyData(CGImageGetDataProvider(inImage));
m_PixelBuf = (UInt8 *) CFDataGetBytePtr(m_DataRef);
length = CFDataGetLength(m_DataRef);

///////Color////////////////    
for (int index = 0; index < length; index += 4)
{
    //Blue
    if((m_PixelBuf[index] + ((int)color * 2))>255){
        m_PixelBuf[index] = 255;
    }else if((m_PixelBuf[index] + ((int)color * 2))<0){
        m_PixelBuf[index] = 0;
    }
    else{
        m_PixelBuf[index]=m_PixelBuf[index] + ((int)color * 2);
    }

    //Green
    if((m_PixelBuf[index+1] + ((int)color * 2))>255){
        m_PixelBuf[index+1] = 255;
    }else if((m_PixelBuf[index+1] + ((int)color * 2))<0){
        m_PixelBuf[index+1] = 0;             
    }
    else{
        m_PixelBuf[index+1]=m_PixelBuf[index+1] + ((int)color * 2);  
    }

    //Red
    if((m_PixelBuf[index+2] + ((int)color * 2))>255){
        m_PixelBuf[index+2] = 255;
    }else if((m_PixelBuf[index+2] + ((int)color * 2))<0){
        m_PixelBuf[index+2] = 0;             
    }
    else{
        m_PixelBuf[index+2]=m_PixelBuf[index+2] + ((int)color * 2);  
    }

    //m_PixelBuf[index+3]=255;//Alpha
}

ctx = CGBitmapContextCreate(m_PixelBuf,  
                            CGImageGetWidth( inImage ),  
                            CGImageGetHeight( inImage ),  
                            CGImageGetBitsPerComponent(inImage),
                            CGImageGetBytesPerRow(inImage ),  
                            CGImageGetColorSpace(inImage ),  
                            CGImageGetBitmapInfo(inImage) );
imageRef = CGBitmapContextCreateImage (ctx);
rawImage = [[UIImage alloc]initWithCGImage:imageRef];
drawImage.image = rawImage;
[rawImage release];
CGContextRelease(ctx); 
CFRelease(imageRef);
CFRelease(m_DataRef);
//drawImage.image = unfilteredImage2;
willUpdate = YES;
}

sorry for any extra comments/info I just copied the whole method in.

Thanks,

Storealutes

Was it helpful?

Solution

I had same problem. You should use below code to get pointer to pixel buffer instead of CFDataGetBytePtr().

CGImageRef cgImage = originalImage.CGImage;
size_t width = CGImageGetWidth(cgImage);
size_t height = CGImageGetHeight(cgImage);

char *buffer = (char*)malloc(sizeof(char) * width * height * 4);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef cgContext = CGBitmapContextCreate(buffer, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedLast);
CGContextSetBlendMode(cgContext, kCGBlendModeCopy);
CGContextDrawImage(cgContext, CGRectMake(0.0f, 0.0f, width, height), cgImage);

free(buffer);
CGContextRelease(cgContext);
CGColorSpaceRelease(colorSpace);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top