package imaging import ( "image" "runtime" "sync" ) // parallel processes the data in separate goroutines. func parallel(start, stop int, fn func(<-chan int)) { count := stop - start if count < 1 { return } procs := runtime.GOMAXPROCS(0) if procs > count { procs = count } c := make(chan int, count) for i := start; i < stop; i++ { c <- i } close(c) var wg sync.WaitGroup for i := 0; i < procs; i++ { wg.Add(1) go func() { defer wg.Done() fn(c) }() } wg.Wait() } // absint returns the absolute value of i. func absint(i int) int { if i < 0 { return -i } return i } // clamp rounds and clamps float64 value to fit into uint8. func clamp(x float64) uint8 { v := int64(x + 0.5) if v > 255 { return 255 } if v > 0 { return uint8(v) } return 0 } func reverse(pix []uint8) { if len(pix) <= 4 { return } i := 0 j := len(pix) - 4 for i < j { pix[i+0], pix[j+0] = pix[j+0], pix[i+0] pix[i+1], pix[j+1] = pix[j+1], pix[i+1] pix[i+2], pix[j+2] = pix[j+2], pix[i+2] pix[i+3], pix[j+3] = pix[j+3], pix[i+3] i += 4 j -= 4 } } func toNRGBA(img image.Image) *image.NRGBA { if img, ok := img.(*image.NRGBA); ok { return &image.NRGBA{ Pix: img.Pix, Stride: img.Stride, Rect: img.Rect.Sub(img.Rect.Min), } } return Clone(img) }