MTLTexture -> CIImage -> CGImage crash on options not nil

I have the following piece of code:

Code Block swift
extension MTLTexture {
public var cgImage: CGImage? {
let ctx = CIContext(mtlDevice: self.device)
let options: [CIImageOption: Any] = [CIImageOption.colorSpace: CGColorSpace.linearSRGB]
guard let image = CIImage(mtlTexture: self, options: options) else {
print("CIImage not created")
return nil
}
guard let imageSrgb = image.matchedToWorkingSpace(from: CGColorSpace(name: CGColorSpace.linearSRGB)!) else {
print("CIImage not converted to srgb")
return nil
}
let flipped = imageSrgb.transformed(by: CGAffineTransform(scaleX: 1, y: -1))
return ctx.createCGImage(flipped, from: flipped.extent)
}
}


This code crashes on line 14 with EXC_BAD_ACCESS code 1 without additional calls. However, when I set options to nil in CIImage call on line 5, it renders fine.

FWIW, there's no change if I remove lines 9-13 and call createCGImage straight from image.

It also crashes, if I instantiate the context without the device:
return CIContext().createCGImage(...)

What am I missing?
Answered by BartW in 671472022
Thanks. It probably was it, but I've found an even neater solution:

Code Block swift
public var cgImage: CGImage? {
guard let image = CIImage(mtlTexture: self, options: nil) else {
print("CIImage not created")
return nil
}
let flipped = image.transformed(by: CGAffineTransform(scaleX: 1, y: -1))
return CIContext().createCGImage(flipped,
from: flipped.extent,
format: CIFormat.RGBA8,
colorSpace: CGColorSpace(name: CGColorSpace.linearSRGB)!)
}


What am I missing?

Have you tried changing line 4 as follows?
Code Block
let options: [CIImageOption: Any] = [CIImageOption.colorSpace: CGColorSpace(name: CGColorSpace.linearSRGB)!]

The doc of CIImageOption.colorSpace says:

The value you supply for this dictionary key must be a CGColorSpace data type.

As you know CGColorSpace.linearSRGB is CFString, not CGColorSpace.

There may be other parts affecting this behavior, so you may have other places to fix. But the value of options seems to be one thing you need to fix.
Accepted Answer
Thanks. It probably was it, but I've found an even neater solution:

Code Block swift
public var cgImage: CGImage? {
guard let image = CIImage(mtlTexture: self, options: nil) else {
print("CIImage not created")
return nil
}
let flipped = image.transformed(by: CGAffineTransform(scaleX: 1, y: -1))
return CIContext().createCGImage(flipped,
from: flipped.extent,
format: CIFormat.RGBA8,
colorSpace: CGColorSpace(name: CGColorSpace.linearSRGB)!)
}


Here is my code from Eugene's Blog(https://eugenebokhan.io/introduction-to-metal-compute-part-four)

public var cgImage: CGImage? {
    let bytesPerRow = self.width * 4
    let length = bytesPerRow * self.height

    let rgbaBytes = UnsafeMutableRawPointer.allocate(byteCount: length, alignment: MemoryLayout<UInt8>.alignment)
     
    defer {
      rgbaBytes.deallocate()
    }

    let destinationRegion = MTLRegion(origin: .init(x: 0, y: 0, z: 0),
                     size: .init(width: self.width,
                           height: self.height,
                           depth: self.depth))
    self.getBytes(rgbaBytes, bytesPerRow: bytesPerRow, from: destinationRegion, mipmapLevel: 0)

    let colorScape = CGColorSpaceCreateDeviceRGB()
    let bitmapInfo = CGBitmapInfo(rawValue: CGImageByteOrderInfo.order32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue)

    guard let data = CFDataCreate(nil, rgbaBytes.assumingMemoryBound(to: UInt8.self), length),
       let dataProvider = CGDataProvider(data: data),
       let cgImage = CGImage(width: self.width,
                  height: self.height,
                  bitsPerComponent: 8,
                  bitsPerPixel: 32,
                  bytesPerRow: bytesPerRow,
                  space: colorScape,
                  bitmapInfo: bitmapInfo,
                  provider: dataProvider,
                  decode: nil,
                  shouldInterpolate: true,
                  intent: .defaultIntent)
    else { return nil }
     
    return cgImage
  }
MTLTexture -&gt; CIImage -&gt; CGImage crash on options not nil
 
 
Q