1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- package imaging
- import (
- "math"
- "runtime"
- "sync"
- "sync/atomic"
- )
- var parallelizationEnabled = true
- // if GOMAXPROCS = 1: no goroutines used
- // if GOMAXPROCS > 1: spawn N=GOMAXPROCS workers in separate goroutines
- func parallel(dataSize int, fn func(partStart, partEnd int)) {
- numGoroutines := 1
- partSize := dataSize
- if parallelizationEnabled {
- numProcs := runtime.GOMAXPROCS(0)
- if numProcs > 1 {
- numGoroutines = numProcs
- partSize = dataSize / (numGoroutines * 10)
- if partSize < 1 {
- partSize = 1
- }
- }
- }
- if numGoroutines == 1 {
- fn(0, dataSize)
- } else {
- var wg sync.WaitGroup
- wg.Add(numGoroutines)
- idx := uint64(0)
- for p := 0; p < numGoroutines; p++ {
- go func() {
- defer wg.Done()
- for {
- partStart := int(atomic.AddUint64(&idx, uint64(partSize))) - partSize
- if partStart >= dataSize {
- break
- }
- partEnd := partStart + partSize
- if partEnd > dataSize {
- partEnd = dataSize
- }
- fn(partStart, partEnd)
- }
- }()
- }
- wg.Wait()
- }
- }
- func absint(i int) int {
- if i < 0 {
- return -i
- }
- return i
- }
- // clamp & round float64 to uint8 (0..255)
- func clamp(v float64) uint8 {
- return uint8(math.Min(math.Max(v, 0.0), 255.0) + 0.5)
- }
- // clamp int32 to uint8 (0..255)
- func clampint32(v int32) uint8 {
- if v < 0 {
- return 0
- } else if v > 255 {
- return 255
- }
- return uint8(v)
- }
|