Skip to content

Commit 87ef772

Browse files
committed
feat: Performance improvements using Accelerate.framework
1 parent 5a12656 commit 87ef772

1 file changed

Lines changed: 53 additions & 2 deletions

File tree

FITScope/Image/ImageRenderer.swift

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import Cocoa
2626
import SwiftFITS
2727
import CoreGraphics
28+
import Accelerate
2829

2930
public 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

Comments
 (0)