| 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) |
| } |