1

I have the following code to create a table for sampling an image in iOS using the Swift accelerate functions

When I rebound the memory to UInt16 which the table creation expects from Int which is the original type I get a fatal error.

var arr = Array<Float>(repeating: 0, count: 163840)

arr.withUnsafeBufferPointer{
    arr_pointer in do {
         arr_pointer.withMemoryRebound(to: UInt16.self){ // This causes a FATAL ERROR
             arr_r_pointer in do {
                 let table = vImageMultidimensionalTable_Create( arr_r_pointer.baseAddress!,
                            3, 3, dims_r_pointer.baseAddress!, kvImageMDTableHint_Float, 
                            vImage_Flags(kvImageNoFlags), nil )                          
                 vImageMultiDimensionalInterpolatedLookupTable_PlanarF( &srcBuffer,
                                       &destBuffer,nil,table!,
                                       kvImageFullInterpolation,
                                      vImage_Flags(kvImageNoFlags))
             }
        }
    }
}

Could anyone point out my mistake here?

Pavan K
  • 4,085
  • 8
  • 41
  • 72
  • What is `arr` ? – OOPer Aug 29 '18 at 16:13
  • @OOPer arr is an array containing values. I added code that is a placeholder. I fill the arr with values inside my code – Pavan K Aug 29 '18 at 16:15
  • Your `arr` is a nested `Array` and the outer `Array` (`arr`) has only 2 elements. So, your code access out of bounds and crash! Use a single dimension `Array` of `81920 * 2` elements. – OOPer Aug 29 '18 at 16:21
  • I flattened the array and have 163840 elements now. it still gives me the same error unfortunately – Pavan K Aug 29 '18 at 16:39
  • I haven't checked the inner parts of your closure but you may have some inconsistency or misusage in your code. `dims_r_pointer`, `srcBuffer`, `destBuffer`... Please disclose all such things. – OOPer Aug 29 '18 at 16:51

2 Answers2

1

You should've read Note for withMemoryRebound function:

Note

Only use this method to rebind the buffer’s memory to a type with the same size and stride as the currently bound Element type. To bind a region of memory to a type that is a different size, convert the buffer to a raw buffer and use the bindMemory(to:) method.

Size of Float is 32 bits, size of UInt16 is 16 bits, so they don't have same size and cannot be rebound.

So you should do something like this:

arr.withUnsafeBufferPointer { pointer in
    let raw = UnsafeRawBufferPointer(pointer)
    let uints = raw.bindMemory(to: UInt16.self)
    // use buffer pointer to `UInt16`s here
}

But also note, that each Float from initial array will be split in two UInt16 that way. I don't know if that's what you need.

user28434'mstep
  • 6,290
  • 2
  • 20
  • 35
0

Your original array arr is an array of Floats

var arr = Array<Float>(repeating: 0, count: 163840)

but you're trying to bind the pointer to a UInt16

arr_pointer.withMemoryRebound(to: UInt16.self)
Ashley Mills
  • 50,474
  • 16
  • 129
  • 160