0

Has anyone else come across this problem? ObjectAlloc climbs as a result of the CGBitmapContextCreateImage. Does Apple's software not fully releasing the objectalloc?

I am resizing images 12 times a second with a NSTimer. During resizing of the image I am also adding a photoshop like Gaussian blur effect by including interpolationQuality.

After using Instruments it does not show any memory leaks but my objectalloc just continues to climb. It points directly to CGBitmapContextCreateImage.
CGBitmapContextCreateImage > create_ bitmap_ data_provide > malloc

Anyone know of a solution? or Even possible ideas?

The Call within the NSTimer

NSString * fileLocation = [[NSBundle mainBundle] pathForResource:imgMain ofType:@"jpg"];
NSData * imageData = [NSData dataWithContentsOfFile:fileLocation];
UIImage * blurMe = [UIImage imageWithData:imageData];

CGRect rect = CGRectMake(0, 0, round(blurMe.size.width /dblBlurLevel), round(blurMe.size.width /dblBlurLevel)); 
UIImage * imageShrink = [self resizedImage: blurMe : rect : 3.0];   

CGRect rect2 = CGRectMake(0, 0, blurMe.size.width , blurMe.size.width ); 
UIImage * imageReize = [self resizedImage: imageShrink : rect2 : 3.0];

imgView.image = imageReize;

The Resize Function

-(UIImage *) resizedImage:(UIImage *)inImage : (CGRect)thumbRect : (double)interpolationQuality
{
    CGImageRef                  imageRef = [inImage CGImage];
    CGImageAlphaInfo    alphaInfo = CGImageGetAlphaInfo(imageRef);

    if (alphaInfo == kCGImageAlphaNone)
        alphaInfo = kCGImageAlphaNoneSkipLast;

    // Build a bitmap context that's the size of the thumbRect
    CGContextRef bitmap = CGBitmapContextCreate(
                                NULL,
                                thumbRect.size.width,
                                thumbRect.size.height,          
                                CGImageGetBitsPerComponent(imageRef),
                                4 * thumbRect.size.width,       
                                CGImageGetColorSpace(imageRef),
                                alphaInfo
                                );

    // Draw into the context, this scales the image
    CGContextSetInterpolationQuality(bitmap, interpolationQuality);
    CGContextDrawImage(bitmap, thumbRect, imageRef);

    // Get an image from the context and a UIImage
    CGImageRef  ref = CGBitmapContextCreateImage(bitmap);
    UIImage*    result = [UIImage imageWithCGImage:ref];

    CGContextRelease(bitmap);   // ok if NULL
    CGImageRelease(ref);

    return [result autorelease];
}
bbullis21
  • 741
  • 3
  • 9
  • 21
  • Are you sure that CGContextSetInterpolationQuality does a Gaussian blur? – mahboudz Sep 17 '09 at 03:03
  • Can you show how you call this method and what you do with the returned image? – coneybeare Sep 17 '09 at 03:26
  • Yes, The way I am using this function works perfect to get a photoshop like Gaussian Blur. I pass a normal UIImage into this script and resize the image to a very small size and add some InterpolationQuality to it. Doing this makes the new very small image blurry. I then call the resize script again and pass it in the shrunken and blurred image I just created. When you scale up small blurred image it comes back with a perfect Gaussian Blur. I have searched all over to find an easy way to add a Gaussian blur but I haven't found a funcation that adds one as good as this. – bbullis21 Sep 17 '09 at 03:27
  • ConeyBeare - Just added some more code – bbullis21 Sep 17 '09 at 03:32

2 Answers2

1

That code overreleases result.

That said, it's likely that the issue is that the UIImage is not getting deallocated, and the UIImage is holding onto the CGImage, and the CGImage is holding onto the memory that was allocated under CGBitmapContextCreate.

Use instruments to see if UIImages are not getting deallocated, and if so try to debug why.

Ken
  • 12,933
  • 4
  • 29
  • 32
  • To make sure that I don't overrelease the result can I just replace.... return [result autorelease] with return result; ....if that is the case then that doesn't fix it either. My original code had it this way, someone gave the advice of adding the autorelease. This CGBitmapContextCreateImage > create_bitmap_data_provide > malloc, is driving me crazy. – bbullis21 Sep 17 '09 at 03:07
  • The overrelease is not the problem, it's something else that's wrong. It's the rest of my comment that's relevant. Check if you're leaking UIImages. – Ken Sep 17 '09 at 04:20
  • Do you check that by selecting, "Created & Still Living", in the Instruments program? Sorry only been coding for 2 months now, so I am still learning – bbullis21 Sep 17 '09 at 04:32
-1

I compiled and ran your code as you have it and I don't see any leaks nor does my object alloc keep climbing. I run the code a couple of times a second and don't see any object growth in Instruments. I am only running on the simulator. I also tried a kCGInterpolationNone instead of 3.0 in case that is the problem, and still no leak.

Not sure why I don't get them and you do. You might want to just do this in the method:

-(UIImage *) resizedImage:(UIImage *)inImage : (CGRect)thumbRect : (double)interpolationQuality
{
    CGImageRef                  imageRef = [inImage CGImage];
    CGImageAlphaInfo    alphaInfo = CGImageGetAlphaInfo(imageRef);

    return inImage;
...

In order to make this method be meaningless and then watch to see if the object alloc continues to grow. If so, then the problem is elsewhere.

mahboudz
  • 39,196
  • 16
  • 97
  • 124
  • I gave this a try and still same result. The ObjectAlloc build up still is pointing to CGBitmapContextCreateImage call. Thanks though. Third day in a row I have been pulling my hair out over this. – bbullis21 Sep 17 '09 at 03:15
  • Try this: instead of providing NULL to CGBitmapCreateContext, pass it bmapPtr = malloc(height*4*thumbRect.size.width); Don't forget to free(bmapPtr) at the end of the method. – mahboudz Sep 17 '09 at 03:28
  • is bmapPtr an int? I am not sure what to declare it as? – bbullis21 Sep 17 '09 at 03:45
  • I declared it as a void * bmapPtr like the class reference file said. It just caused the image to freeze and crashed. – bbullis21 Sep 17 '09 at 03:50
  • No, you never release something that you got with a get method. [Memory rules for CoreFoundation][1]. [1]: http://developer.apple.com/mac/library/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-CJBEJBHH – Ken Sep 17 '09 at 04:19
  • Those docs are saying that if you want to keep it around, you'd have to retain it. It would have been better not to say anything here; it's the usual rule. – Ken Sep 17 '09 at 04:21