2525import Cocoa
2626import SwiftFITS
2727import CoreGraphics
28+ import Accelerate
2829
2930public class ImageRenderer
3031{
@@ -191,7 +192,7 @@ public class ImageRenderer
191192
192193 let scaled = Benchmark . run ( label: " Applying Scale " )
193194 {
194- self . scale ( pixels: raw, scale: options. scale, offset: options. scaleOffset )
195+ self . scaleWithAccelerate ( pixels: raw, scale: options. scale, offset: options. scaleOffset )
195196 }
196197
197198 let rgb = if let pattern = options. bayerPattern
@@ -211,7 +212,7 @@ public class ImageRenderer
211212
212213 let normalized = Benchmark . run ( label: " Normalizing Pixels " )
213214 {
214- self . normalize ( pixels: rgb )
215+ self . normalizeWithAccelerate ( pixels: rgb )
215216 }
216217
217218 guard let provider = CGDataProvider ( data: Data ( normalized ) as CFData )
@@ -321,6 +322,18 @@ public class ImageRenderer
321322 }
322323 }
323324
325+ public class func scaleWithAccelerate( pixels: [ Double ] , scale: Double , offset: Int64 ) -> [ Double ]
326+ {
327+ var result = [ Double ] ( repeating: 0.0 , count: pixels. count )
328+ var scalar = scale
329+ var addend = Double ( offset )
330+
331+ vDSP_vsmulD ( pixels, 1 , & scalar, & result, 1 , vDSP_Length ( pixels. count ) )
332+ vDSP_vsaddD ( result, 1 , & addend, & result, 1 , vDSP_Length ( pixels. count ) )
333+
334+ return result
335+ }
336+
324337 public class func normalize( pixels: [ Double ] ) -> [ UInt8 ]
325338 {
326339 let minPixel = pixels. min ( ) ?? 0
@@ -332,4 +345,42 @@ public class ImageRenderer
332345 UInt8 ( max ( 0 , min ( 255 , ( $0 - minPixel ) / range * 255.0 ) ) )
333346 }
334347 }
348+
349+ public class func normalizeWithAccelerate( pixels: [ Double ] ) -> [ UInt8 ]
350+ {
351+ guard pixels. isEmpty == false
352+ else
353+ {
354+ return [ ]
355+ }
356+
357+ var minPixel = 0.0
358+ var maxPixel = 0.0
359+
360+ vDSP_minvD ( pixels, 1 , & minPixel, vDSP_Length ( pixels. count ) )
361+ vDSP_maxvD ( pixels, 1 , & maxPixel, vDSP_Length ( pixels. count ) )
362+
363+ let range = max ( 1.0 , maxPixel - minPixel )
364+ let scale = 255.0 / range
365+ let offset = - minPixel * scale
366+ var normalized = [ Double ] ( repeating: 0.0 , count: pixels. count )
367+
368+ vDSP_vsmsaD ( pixels, 1 , [ scale ] , [ offset ] , & normalized, 1 , vDSP_Length ( pixels. count ) )
369+
370+ var clipped = [ Double ] ( repeating: 0.0 , count: pixels. count )
371+ var lowerBound = 0.0
372+ var upperBound = 255.0
373+
374+ vDSP_vclipD ( normalized, 1 , & lowerBound, & upperBound, & clipped, 1 , vDSP_Length ( pixels. count ) )
375+
376+ var floatPixels = [ Float ] ( repeating: 0.0 , count: pixels. count )
377+
378+ vDSP_vdpsp ( clipped, 1 , & floatPixels, 1 , vDSP_Length ( pixels. count ) )
379+
380+ var result = [ UInt8 ] ( repeating: 0 , count: pixels. count )
381+
382+ vDSP_vfixu8 ( floatPixels, 1 , & result, 1 , vDSP_Length ( pixels. count ) )
383+
384+ return result
385+ }
335386}
0 commit comments