UInt8 EXC_BAD_ACCESS

时间:2012-09-07 04:11:53

标签: image filter buffer exc-bad-access uint

我有一个方法可以为图像添加过滤器。这个工作正常,直到几个月前,现在当我尝试使用此方法时,应用程序将在图像缓冲区崩溃。我创建缓冲区并将其设置为图像的数据,稍后访问特定索引会导致访问崩溃。我已经找了一两个小时,现在我确信有一些东西可以忽略。我认为应该发布一些不应该发布的内容。我正在使用xos的ios DP 4预览版,我认为这个问题始于测试版的更新,但我真的不确定。

这是第一个 for循环的中间附近崩溃的行

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

通常它设置为aRed我已经检查过,它不应该超出缓冲区边界。

    -(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;
}

抱歉,我刚刚复制了整个方法的任何额外评论/信息。

谢谢,

Storealutes

1 个答案:

答案 0 :(得分:1)

我有同样的问题。 您应该使用下面的代码来获取指向像素缓冲区的指针,而不是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);