diff --git a/mobile/ios/Runner/Images/ImageProcessing.swift b/mobile/ios/Runner/Images/ImageProcessing.swift index f7ec72101..450cac04f 100644 --- a/mobile/ios/Runner/Images/ImageProcessing.swift +++ b/mobile/ios/Runner/Images/ImageProcessing.swift @@ -1,3 +1,4 @@ +import Accelerate import Foundation enum ImageProcessing { @@ -11,4 +12,22 @@ enum ImageProcessing { static let cancelledResult = Result<[String: Int64]?, any Error>.success(nil) // Impeller shrinks each side to the GPU texture limit on its own, which squishes long images. static let maxPixelSize = 16384 + + static func rgbaBuffer(_ image: CGImage, format: vImage_CGImageFormat) throws -> vImage_Buffer { + guard image.bitsPerComponent == 10 else { + return try vImage_Buffer(cgImage: image, format: format) + } + + // vImage can't convert packed 10-bit images. + let buffer = try vImage_Buffer(width: image.width, height: image.height, bitsPerPixel: format.bitsPerPixel) + guard let context = CGContext(data: buffer.data, width: image.width, height: image.height, bitsPerComponent: Int(format.bitsPerComponent), bytesPerRow: buffer.rowBytes, space: format.colorSpace.takeUnretainedValue(), bitmapInfo: format.bitmapInfo.rawValue) else { + buffer.free() + throw vImage.Error.invalidImageFormat + } + + context.setRenderingIntent(format.renderingIntent) + context.setBlendMode(.copy) + context.draw(image, in: CGRect(x: 0, y: 0, width: image.width, height: image.height)) + return buffer + } } diff --git a/mobile/ios/Runner/Images/LocalImagesImpl.swift b/mobile/ios/Runner/Images/LocalImagesImpl.swift index 4ef2d9304..8fce96627 100644 --- a/mobile/ios/Runner/Images/LocalImagesImpl.swift +++ b/mobile/ios/Runner/Images/LocalImagesImpl.swift @@ -165,7 +165,7 @@ class LocalImageApiImpl: LocalImageApi { } do { - let buffer = try vImage_Buffer(cgImage: cgImage, format: Self.rgbaFormat) + let buffer = try ImageProcessing.rgbaBuffer(cgImage, format: Self.rgbaFormat) if request.isCancelled { buffer.free() diff --git a/mobile/ios/Runner/Images/RemoteImagesImpl.swift b/mobile/ios/Runner/Images/RemoteImagesImpl.swift index c409b5d1e..74b50c6c0 100644 --- a/mobile/ios/Runner/Images/RemoteImagesImpl.swift +++ b/mobile/ios/Runner/Images/RemoteImagesImpl.swift @@ -148,7 +148,7 @@ class RemoteImageApiImpl: NSObject, RemoteImageApi { } do { - let buffer = try vImage_Buffer(cgImage: cgImage, format: rgbaFormat) + let buffer = try ImageProcessing.rgbaBuffer(cgImage, format: rgbaFormat) if request.isCancelled { buffer.free()