What I want to Work
My end goal is to have Array Data such as [Int]
, [UInt]
, [Float]
passed through a generic function that converts any of these types and outputs the [UInt8]
0-255 values for pixel data. This is so I can make a Pointer to this UInt8
data, create a CFData
(built-in type) out of this pointer, then finally give the CFData
to a CGDataProvider
and have this as the input to generate a grayscale Image from CGImage.init()
. (This process could be simpler I think, but this is how I figured it out.)
My function I will have for reading looks like this:
mutating func fromfileBI<T : BinaryInteger>(count : Int = 1) -> [T]? {
let byteSize = MemoryLayout<T>.stride
var swiftTypeOut : [T] = []
if count > 1 {
swiftTypeOut = [T].init(repeating: 0, count: count)
for i in 0...count-1 {
swiftTypeOut[i] = data.subdata(in: off + i * byteSize..<off + (i + 1) * byteSize ).withUnsafeBytes{ $0.load(as: T.self )}
}
off += count * byteSize
}
else if count == 1 {
swiftTypeOut = [ data.subdata(in: off..<(off+1) * byteSize ).withUnsafeBytes{ $0.load(as: T.self )} ]
off += byteSize
}
else if count == 0 {
return []
} else if count < 0 {
print("Warning, fRead.int8Read( count : Int = 1) called with a negative count, returning empty array.")
return []
}
return swiftTypeOut
}
However there is also an identical bodied function for BinaryFloatingPoint (BF)
mutating func fromfileBF<T : BinaryFloatingPoint>(count : Int = 1) -> [T]?
And the functions for formating the image data (This last step is all I care about... All the data will make it to the Image without any need of sharing the original type of the data (data will be [UInt8] returning from this function)).
Here is the one for BinaryInteger conforming types.:
func formatArrayDataforImage<T>(dataSet : Array< T >, count: Int, numpyTypeName : String = "") -> [UInt8]! where T: BinaryInteger {
var f32Data = [Float](repeating: 0, count: count)
let obj = f32Data as NSObject // Object to synchronise
var UInt8BytesOut = [UInt8](repeating: 0, count: count)
DispatchQueue.concurrentPerform(iterations: count){ index in
synchronized(obj) {
let dataSetValue = dataSet[index]
f32Data[index] = Float( dataSetValue )
}
} // This DispatchQueue thing was necessary when I was dealing with pointers as input, Now I dont know.
guard let max = f32Data.max() else { fatalError("Find max fail.")}
guard let min = f32Data.min() else { fatalError("find min fail.")}
for i in 0..<f32Data.count {
f32Data[i] -= min
f32Data[i] = 255 * f32Data[i] / max
UInt8BytesOut[i] = UInt8( f32Data[i] )
if i<100 {
print(UInt8BytesOut[i])
}
}
return UInt8BytesOut
}
I guess the other formatArrayDataforImage<T: BinaryFloatingPoint>
will simply have the difference where Float(dataSetValue)
which should work too, I think it's fine for Float32
to be cast to Float
and Float8
etc. But the function call was demanding BinaryInteger
conformance so we'll see.
RAMBLE:(skip it's only for context)–––––––
I have fixed a function that reads bytes and outputs them as the type desired, I've hardcoded all the way to getting one dataset loaded as type [UInt16], and this works. But I knew from the start I would have to learn about how to make the handling of types completely automatic. (The project code is somewhat embarrassing... I know I have to switch on a String value read from the source file to determine Swift datatype once.. but I ended up needing this switch often when reading, and right now I may have to hardcode the switch again.. how am I going to get the Swift data type known by whatever function is calling it? I don't want to use separate cases like switching on a datatype then casting var example_variable = dataWhosTypeIKnowOnly_FromRawString as [Int32] // <--I know your type from hardcoding the switch
I suspect the answer to my question to be buried somewhere in this answer–C# generics: cast generic type to value type
But given I'm dealing with wanting my generic-typed array specified for the creation of a pointer, I'm not sure how that could change things.
––––––––.
END Hope to learn once and for all how to become clear on proper Swift Type handling.