Search code examples
iosswiftgpuimageunsafe-pointers

Working with UnsafeMutablePointer array


I'm trying to work with Brad Larson's splendid GPUImage framework, and I'm struggling to process the cornerArray returned by the GPUImageHarrisCornerDetectionFilter.

The corners are returned as an array of GLFloat in an UnsafeMutablePointer - and I would like to convert that to an array of CGPoint

I've tried allocating space for the memory

var cornerPointer = UnsafeMutablePointer<GLfloat>.alloc(Int(cornersDetected) * 2)

but the data doesn't seem to make any sense - either zero or 1E-32

I found what looked like the perfect answer how to loop through elements of array of <UnsafeMutablePointer> in Swift and tried

filter.cornersDetectedBlock = {(cornerArray:UnsafeMutablePointer<GLfloat>, cornersDetected:UInt, frameTime:CMTime) in
        crosshairGenerator.renderCrosshairsFromArray(cornerArray, count:cornersDetected, frameTime:frameTime)

    for floatData in UnsafeBufferPointer(start: cornerArray, count: cornersDetected)
    {
        println("\(floatData)")
    }

but the compiler didn't like the UnsafeBufferPointer - so I changed it to UnsafeMutablePointer, but it didn't like the argument list.

I'm sure this is nice and simple, and it sounds like something other people must have had to do - so what's the solution?


Solution

  • The UnsafeMutablePointer<GLfloat> type translated from C can have its elements accessed via a subscript, just like a normal array. To achieve your goal of converting these to CGPoints, I'd use the following code:

    filter.cornersDetectedBlock = { (cornerArray:UnsafeMutablePointer<GLfloat>, cornersDetected:UInt, frameTime:CMTime) in
        var points = [CGPoint]()
        for index in 0..<Int(cornersDetected) {
           points.append(CGPoint(x:CGFloat(cornerArray[index * 2]), y:CGFloat(cornerArray[(index * 2) + 1])))
        }
        // Do something with these points
    }
    

    The memory backing cornerArray is allocated immediately before the callback is triggered, and deallocated immediately after it. Unless you copy these values over in the middle of the block, as I do above, I'm afraid that you'll leave yourself open to some nasty bugs. It's also easier to convert to the correct format at that point, anyway.