1

I am maintaining a company's legacy app and am trying to reduce the amounts of crashes and memory leaks in a non-ARC project (sigh). I have identified a massive memory leak in a function that converts a PDF file into a UIImage but do not have enough experience with graphics contexts to identify all the issues properly.

The method which is leaking memory is as follows:

+ (UIImage *) convertPDFToImage:(NSURL *)pdfLocation withResolution:(int)resolution withProductKey:(NSString *) productKey {

CGPDFDocumentRef documentRef = CGPDFDocumentCreateWithURL((CFURLRef)pdfLocation);

if(!CGPDFDocumentIsUnlocked(documentRef))
{
    NSString *hashedPassword = [MD5Hash CreateMD5HashForPDFPasswordUsingProductKey:productKey];
    CGPDFDocumentUnlockWithPassword(documentRef, [hashedPassword UTF8String]);
}

CGPDFPageRef page = CGPDFDocumentGetPage(documentRef, 1); 

CGRect cropBox = CGPDFPageGetBoxRect(page, kCGPDFCropBox);
int pageRotation = CGPDFPageGetRotationAngle(page);

if ((pageRotation == 0) || (pageRotation == 180) ||(pageRotation == -180)) {
    UIGraphicsBeginImageContextWithOptions(cropBox.size, NO, resolution / 72); 
} else {
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(cropBox.size.height, cropBox.size.width), NO, resolution / 72); 
}

CGContextRef context = UIGraphicsGetCurrentContext();  

CGPoint point = CGPointMake(0, 0);
int rotate = CGPDFPageGetRotationAngle(page);
int zoom = 100;
CGContextSaveGState(context);

// Setup the coordinate system.
// Top left corner of the displayed page must be located at the point specified by the 'point' parameter.
CGContextTranslateCTM(context, point.x, point.y);

// Scale the page to desired zoom level.
CGContextScaleCTM(context, zoom / 100, zoom / 100);

// The coordinate system must be set to match the PDF coordinate system.
switch (rotate) {
    case 0:
        CGContextTranslateCTM(context, 0, cropBox.size.height);
        CGContextScaleCTM(context, 1, -1);
        break;
    case 90:
        CGContextScaleCTM(context, 1, -1);
        CGContextRotateCTM(context, -M_PI / 2);
        break;
    case 180:
    case -180:
        CGContextScaleCTM(context, 1, -1);
        CGContextTranslateCTM(context, cropBox.size.width, 0);
        CGContextRotateCTM(context, M_PI);
        break;
    case 270:
    case -90:
        CGContextTranslateCTM(context, cropBox.size.height, cropBox.size.width);
        CGContextRotateCTM(context, M_PI / 2);
        CGContextScaleCTM(context, -1, 1);
        break;
}

// The CropBox defines the page visible area, clip everything outside it.
CGRect clipRect = CGRectMake(0, 0, cropBox.size.width, cropBox.size.height);

CGContextAddRect(context, clipRect);
CGContextClip(context);

CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0);
CGContextFillRect(context, clipRect);

CGContextTranslateCTM(context, -cropBox.origin.x, -cropBox.origin.y);

CGContextSetInterpolationQuality(context, kCGInterpolationHigh); 
CGContextSetRenderingIntent(context, kCGRenderingIntentDefault);

CGContextDrawPDFPage(context, page);    

UIImage *pageImage = UIGraphicsGetImageFromCurrentImageContext(); 

CGContextRestoreGState(context);
UIGraphicsEndImageContext();

CGPDFPageRelease(page);
CGPDFDocumentRelease(documentRef);

return pageImage;
}

I have already solved one leak where the CGPDFPage was not being released, but the profile shows that this method is still leaking slightly.

Any suggestions would be much appreciated

Nick Kirsten
  • 1,187
  • 11
  • 27
  • why cannot select the file and goto xcode edit option and convert to Objective c ARC file.Hope you do this.instead trying to fix everything. – iOSdev Sep 26 '14 at 10:37
  • unfortunately it is a massive project that was created years ago. Converting to ARC is going to take time that they are not willing to pay for. Instead they want as many issues fixed as possible without a conversion to ARC – Nick Kirsten Sep 26 '14 at 10:47

0 Answers0