utils.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package imaging
  2. import (
  3. "math"
  4. "runtime"
  5. "sync"
  6. "sync/atomic"
  7. )
  8. var parallelizationEnabled = true
  9. // if GOMAXPROCS = 1: no goroutines used
  10. // if GOMAXPROCS > 1: spawn N=GOMAXPROCS workers in separate goroutines
  11. func parallel(dataSize int, fn func(partStart, partEnd int)) {
  12. numGoroutines := 1
  13. partSize := dataSize
  14. if parallelizationEnabled {
  15. numProcs := runtime.GOMAXPROCS(0)
  16. if numProcs > 1 {
  17. numGoroutines = numProcs
  18. partSize = dataSize / (numGoroutines * 10)
  19. if partSize < 1 {
  20. partSize = 1
  21. }
  22. }
  23. }
  24. if numGoroutines == 1 {
  25. fn(0, dataSize)
  26. } else {
  27. var wg sync.WaitGroup
  28. wg.Add(numGoroutines)
  29. idx := uint64(0)
  30. for p := 0; p < numGoroutines; p++ {
  31. go func() {
  32. defer wg.Done()
  33. for {
  34. partStart := int(atomic.AddUint64(&idx, uint64(partSize))) - partSize
  35. if partStart >= dataSize {
  36. break
  37. }
  38. partEnd := partStart + partSize
  39. if partEnd > dataSize {
  40. partEnd = dataSize
  41. }
  42. fn(partStart, partEnd)
  43. }
  44. }()
  45. }
  46. wg.Wait()
  47. }
  48. }
  49. func absint(i int) int {
  50. if i < 0 {
  51. return -i
  52. }
  53. return i
  54. }
  55. // clamp & round float64 to uint8 (0..255)
  56. func clamp(v float64) uint8 {
  57. return uint8(math.Min(math.Max(v, 0.0), 255.0) + 0.5)
  58. }
  59. // clamp int32 to uint8 (0..255)
  60. func clampint32(v int32) uint8 {
  61. if v < 0 {
  62. return 0
  63. } else if v > 255 {
  64. return 255
  65. }
  66. return uint8(v)
  67. }