App terminated to memory issues when performing CGImageDestinationFinalize on large images

Originator:UrKHeH
Number:rdar://31811274 Date Originated:25/4/2017
Status:Open Resolved:
Product:iPhone 6 Product Version:iOS 10.2.1
Classification:Crash/Hang/Data Loss Reproducible:Always
 
When storing large images using Image I/O of extremely large size (20,000x20,000) pixels the application is terminates due to memory issue.

Steps to Reproduce

executing the following code as a part of an application and calling testPhoto with valid photo URL (photo-asset://) of extremely large size terminates the application:

    func testPhoto(url: URL) {
        let result = PHAsset.fetchAssets(withALAssetURLs: [url], options: nil)

        guard result.count > 0 else {
            NSLog("Failed to load image")
            return
        }

        PHCachingImageManager
            .default()
            .requestImageData(for: result.firstObject!, options: nil) {
                (data, uti, orientation, info) in
                _ = self.addExif(data: data!)
        }
    }

    func addExif(data: Data) -> NSData? {
        let selectedImageSourceRef = CGImageSourceCreateWithData(data as CFData, nil)!

        let imagePropertiesDictionaryRef =
            CGImageSourceCopyPropertiesAtIndex(selectedImageSourceRef, 0, nil)

        var imagePropsDictionary: [String: Any] =
            imagePropertiesDictionaryRef as! [String : Any]

        var exifData = [String: Any]()

        let tempFileUrl = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
            .appendingPathComponent(NSUUID().uuidString)
            .appendingPathExtension("jpg")

        guard let imageDestination = CGImageDestinationCreateWithURL(tempFileUrl as CFURL, kUTTypeJPEG, 1, nil) else {
            NSLog("Could not create destination file")
            return nil
        }

        exifData[kCGImagePropertyExifDateTimeOriginal as String] = NSDate()

        imagePropsDictionary[kCGImagePropertyExifDictionary as String] = exifData

        CGImageDestinationAddImageFromSource(
            imageDestination,
            selectedImageSourceRef,
            0,
            imagePropsDictionary as CFDictionary)
        
        if !CGImageDestinationFinalize(imageDestination) {
            NSLog("Could not finalize")
        } else {
            NSLog("New image created")
        }
        
        return nil
    }


Expected Results

CGImageDestinationFinalize either succeeds and creates output image or returns nil in case of failure (for example, for large images).

Actual Results
The application is terminated due to memory issue.

Comments

Apple Developer Relations

Please attach sample image and crashlog.


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!