This repository has been archived by the owner on Dec 28, 2022. It is now read-only.
/
effects.go
78 lines (62 loc) · 1.5 KB
/
effects.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package effects
import (
"math"
"sync"
)
// Effect interface for any effect type
type Effect interface {
// Apply applies the effect to the input image and returns an output image
Apply(img *Image, numRoutines int) (*Image, error)
}
type pixelFunc func(ri, x, y, offset, inStride int, inPix, outPix []uint8)
func runParallel(numRoutines int, inImg *Image, inBounds Rect, outImg *Image, pf pixelFunc, blockWidth int) {
w := inBounds.Width
h := inBounds.Height
minX := inBounds.X
minY := inBounds.Y
stride := inImg.img.Stride
inPix := inImg.img.Pix
outPix := outImg.img.Pix
wg := sync.WaitGroup{}
xOffset := minX
var widthPerRoutine int
if blockWidth != 0 {
widthPerRoutine = blockWidth
} else {
widthPerRoutine = w / numRoutines
}
for r := 0; r < numRoutines; r++ {
wg.Add(1)
if r == numRoutines-1 {
widthPerRoutine = (minX + w) - xOffset
}
go func(ri, xStart, yStart, width, height int) {
for x := xStart; x < xStart+width; x++ {
for y := yStart; y < yStart+height; y++ {
offset := y*stride + x*4
pf(ri, x, y, offset, stride, inPix, outPix)
}
}
wg.Done()
}(r, xOffset, minY, widthPerRoutine, h)
xOffset += widthPerRoutine
}
wg.Wait()
}
func roundToInt32(a float64) int32 {
if a < 0 {
return int32(a - 0.5)
}
return int32(a + 0.5)
}
func rangeInt(i, min, max int) int {
return int(math.Min(math.Max(float64(i), float64(min)), float64(max)))
}
func isOddInt(i int) bool {
return i%2 != 0
}
func reset(s []int) {
for i := range s {
s[i] = 0
}
}