Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 290
Russell Avatar asked Feb 10 '16 09:02

Russell


2 Answers

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.

like image 119
Brad Larson Avatar answered Oct 20 '22 08:10

Brad Larson


I have found a solution - and it's simple. The answer was here https://gist.github.com/kirsteins/6d6e96380db677169831

var dataArray = Array(UnsafeBufferPointer(start: cornerArray, count: Int(cornersDetected) * 2))
like image 3
Russell Avatar answered Oct 20 '22 10:10

Russell