title: How can I release a CVPixelBuffer after passing it to CoreImage/UIKit in Swift?
body: <p>I'm using <code>CVPixelBufferCreateWithBytes(_:_:_:_:_:_:_:_:_:_:)</code> to read a 24-bit BMP from disk:</p>
  <pre><code>var data = try! Data(contentsOf: url.appendingPathExtension(for: .bmp))
  data.withUnsafeMutableBytes { (unsafeMutableRawBufferPointer: UnsafeMutableRawBufferPointer) in
    var pixelBuffer: CVPixelBuffer?
    CVPixelBufferCreateWithBytes(
      kCFAllocatorDefault,
      imageWidth,
      imageHeight,
      kCVPixelFormatType_24RGB,
      unsafeMutableRawBufferPointer.baseAddress!,
      bytesPerRow,
      nil, nil, nil,
      &amp;pixelBuffer
    )
  }
  </code></pre>
  <p>I need to convert it to JPEG, but all the methods I've tried leak, i.e.:</p>
  <pre><code>try! UIImage(ciImage: CIImage(cvPixelBuffer: pixelBuffer!))
      .jpegData(compressionQuality: 0.0)!
      .write(to: someUrl)
  </code></pre>
  <p>and:</p>
  <pre><code>try! CIContext().writeJPEGRepresentation(
      of: CIImage(cvPixelBuffer: pixelBuffer!),
      to: someUrl,
      colorSpace: CGColorSpaceCreateDeviceRGB()
  )
  </code></pre>
  <p><code>autoreleasepool</code> doesn't help:</p>
  <pre><code>autoreleasepool {
    var pixelBuffer: CVPixelBuffer?
    CVPixelBufferCreateWithBytes(
      kCFAllocatorDefault,
      imageWidth,
      imageHeight,
      kCVPixelFormatType_24RGB,
      unsafeMutableRawBufferPointer.baseAddress!,
      bytesPerRow,
      nil, nil, nil,
      &amp;pixelBuffer
    )
    try! UIImage(ciImage: CIImage(cvPixelBuffer: pixelBuffer!))
      .jpegData(compressionQuality: 0.0)!
      .write(to: someUrl)
  }
  </code></pre>
  <p>And none of the <code>*Release</code> methods are available, they produce compiler errors like: <code>'CFRelease' is unavailable: Core Foundation objects are automatically memory managed</code>.</p>
  <p>The issue seems to be the pointer gets retained when any of the JPEG-related methods get called. This leaks:</p>
  <pre><code>let uiImage = UIImage(ciImage: CIImage(cvPixelBuffer: pixelBuffer!))
      .jpegData(compressionQuality: 0.0)!
  </code></pre>
  <p>But this doesn't:</p>
  <pre><code>let uiImage = UIImage(ciImage: CIImage(cvPixelBuffer: pixelBuffer!))
  </code></pre>
  <p>Same with Core Image. This doesn't leak:</p>
  <pre><code>CIContext().createCGImage(CIImage(cvPixelBuffer: pixelBuffer!), from: CGRect(x: 0, y: 0, width: imageWidth, height: imageHeight))
  </code></pre>
  <p>But this does:</p>
  <pre><code>CIContext().writeJPEGRepresentation(
      of: CIImage(cvPixelBuffer: pixelBuffer!),
      to: someUrl,
      colorSpace: CGColorSpaceCreateDeviceRGB()
  )
  </code></pre>
  <p>I guess I need to release the memory by passing <code>CVPixelBufferReleaseBytesCallback</code> to seems to <code>CVPixelBufferCreateWithBytes</code>, but it's not clear to me how to use it in this case. Most examples suggests doing something like:</p>
  <pre><code>let releaseCallBack: CVPixelBufferReleaseBytesCallback = { _, pointer in
    if let pointer = pointer {
       free(UnsafeMutableRawPointer(mutating: pointer))
    }
  }
  </code></pre>
  <p>But it makes the <code>autoreleasepool</code> call to throw because it's trying to free memory that's not there any more, and removing it makes other objects to keep leaking. Manually calling <code>deallocate</code> on the point doesn't help either</p>