Ad

Our DNA is written in Swift
Jump

Regression: CGImageSource doesn’t render background image of certain PDFs

This is a curious bug in Mohave, which is causing some headache for a client of ours who is relying on this functionality in their production work flow, but since this is broken in Mohave they cannot use machines they have already upgraded for this.

And before you ask why we didn’t report this earlier, as there were several months between WWDC and now… well, we didn’t use Mohave in production and it didn’t occur to us that something that was working before could be broken in a nice and shine new macOS version… ๐Ÿ™‚

Filed in OpenRadar and under rdar://45338633. Due to the proprietary nature of the sample PDF, I didn’t post that to my Radar samples repo.

Summary

CGImageSource as of Mohave is no longer able to render the background images for certain PDFs coming out of Adobe InDesign CC2018. This is a regression because on earlier macOS versions this worked fine.

Steps to Reproduce

Build&run the provided sample app on Mohave

Expected Results

  • you should see the background image with the woman

Actual Results

  • you only see some text and boxes in the foreground, the background where the image with the woman should be, is left blank
    On the console you see the output:

    [Cocoanetics.CGImageSourcePDFBug] img_alphamerge_stage: Assertion failed - 
         unknown source alpha

Here’s the code I am using to generate thumbnails

import Cocoa

class ViewController: NSViewController {

    @IBOutlet weak var imageView: NSImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        
        // You can look at Sample1.pdf and Sample2.pdf
        
        let url = Bundle.main.url(forResource: "Sample1", withExtension: "pdf")!
        let data = try! Data(contentsOf: url)
        let source = CGImageSourceCreateWithData(data as CFData, nil)!
        
        let thumbnail = thumbnailImageFromImageSource(source)
        imageView.image = thumbnail
    }
}


// MARK: - Helper Functions

func thumbnailImageFromImageSource(_ imageSource: CGImageSource, 
                                   subAssetIndex: Int? = nil) -> NSImage?
{
    let options: Dictionary <String, AnyObject> 
           = [ kCGImageSourceThumbnailMaxPixelSize as String: 360 as AnyObject,
               kCGImageSourceCreateThumbnailFromImageAlways as String: true
                 as AnyObject,
               kCGImageSourceCreateThumbnailWithTransform as String: true
                 as AnyObject]
    let index = (subAssetIndex ?? 1) - 1
    
    guard let thumbnail 
           = CGImageSourceCreateThumbnailAtIndex(imageSource, 
                                                 index, 
                                                 options as CFDictionary?) 
        else
    {
        NSLog("Unable to generate thumbnail!")
        
        return nil
    }
    
    return NSImage(cgImage: thumbnail, size: NSZeroSize)
}

Also published on Medium.


Categories: Bug Reports

Leave a Comment