Hi, All:
The code below will get different behaviors when running on a Simulator or Real device, can anyone point out what causes this issue?
when running on device will get bad access issue
let pixels = UnsafeMutablePointer(mutating: $0) //Thread 1: EXC_BAD_ACCESS (code=1, address=0x103b98000)
when running on the simulator everything is OK
public struct PixelARGB {
public var a: UInt8 = 0
public var r: UInt8 = 0
public var g: UInt8 = 0
public var b: UInt8 = 0
public init(a:UInt8, r:UInt8, g:UInt8, b:UInt8) {
self.a = a
self.r = r
self.g = g
self.b = b
}
public init() {}
}
public struct PixelRGBA {
public var r: UInt8 = 0
public var g: UInt8 = 0
public var b: UInt8 = 0
public var a: UInt8 = 0
public init(r:UInt8, g:UInt8, b:UInt8, a:UInt8) {
self.r = r
self.g = g
self.b = b
self.a = a
}
public init() {}
}
extension UIImage {
public func transformPixels<T>(_ transformer:
(_ x: Int, _ y: Int, _ r: UInt8, _ g: UInt8, _ b: UInt8, _ a: UInt8) -> T ) -> [T]? {
guard let dataProvider = self.cgImage?.dataProvider,
let alphaInfo = self.cgImage?.alphaInfo,
let pointer = CFDataGetBytePtr(dataProvider.data) else {
return nil
}
let width = Int(self.size.width)
let height = Int(self.size.height)
let length = width * height
switch alphaInfo {
case .first, .premultipliedFirst, .noneSkipFirst:
return pointer.withMemoryRebound(to: PixelARGB.self, capacity: length) {
let pixels = UnsafeMutablePointer<PixelARGB>(mutating: $0)
var result = [T]()
result.reserveCapacity(length)
for y in 0 ..< height {
for x in 0 ..< width {
let i = width * y + x
let pixel = pixels[i]
result.append(transformer(x, y, pixel.r, pixel.g, pixel.b, pixel.a))
}
}
return result
}
case .last, .premultipliedLast, .noneSkipLast:
return pointer.withMemoryRebound(to: PixelRGBA.self, capacity: length) {
let pixels = UnsafeMutablePointer<PixelRGBA>(mutating: $0)
var result = [T]()
result.reserveCapacity(length)
for y in 0 ..< height {
for x in 0 ..< width {
let i = width * y + x
let pixel = pixels[i]
result.append(transformer(x, y, pixel.r, pixel.g, pixel.b, pixel.a))
}
}
return result
}
default: return nil
}
}
}