This repository has been archived by the owner on May 28, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
glitch.go
107 lines (98 loc) · 2.53 KB
/
glitch.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package horizon
import (
"fmt"
"context"
"gocv.io/x/gocv"
"github.com/d5/tengo/v2"
"github.com/sug0/horizon/script"
)
var (
ErrNotRGBImage = fmt.Errorf("horizon: not an rgb image")
)
func Glitch(ctx context.Context, s *script.Script, mat gocv.Mat) (glitched gocv.Mat, err error) {
if mat.Type() != gocv.MatTypeCV8UC3 {
err = ErrNotRGBImage
return
}
width := int64(mat.Cols())
height := int64(mat.Rows())
glitched = mat.Clone()
bitmapMat := mat.DataPtrUint8()
bitmapGlitched := glitched.DataPtrUint8()
var x, y int64
var coords [2]tengo.Int
pixel := tengo.Array{
Value: []tengo.Object{
&tengo.Int{},
&tengo.Int{},
&tengo.Int{},
},
}
persistent := tengo.Map{
Value: make(map[string]tengo.Object),
}
vm := s.BootstrapVM(
&pixel,
&coords[0],
&coords[1],
&builtinConvI64{},
&builtinConvF64{},
&builtinGetPixel{
bitmap: bitmapMat,
width: width,
height: height,
},
&tengo.Int{Value: width},
&tengo.Int{Value: height},
&persistent,
)
glitchRoundWait := make(chan error)
glitchRound := func(i int) {
// run vm
err = vm.Run()
if err != nil {
glitchRoundWait <- err
return
}
// get glitched pixel and set it
bitmapGlitched[i+0] = byte(getPixel(&pixel, 0) & 0xff)
bitmapGlitched[i+1] = byte(getPixel(&pixel, 1) & 0xff)
bitmapGlitched[i+2] = byte(getPixel(&pixel, 2) & 0xff)
// update coords
if x == width-1 {
x = 0
y++
} else {
x++
}
coords[0].Value = int64(x)
coords[1].Value = int64(y)
glitchRoundWait <- nil
}
for i := 0; i < len(bitmapMat); i += 3 {
go glitchRound(i)
select {
case err = <-glitchRoundWait:
if err != nil {
glitched.Close()
err = fmt.Errorf("horizon: vm failed whilst running: %w", err)
return
}
case <-ctx.Done():
vm.Abort()
}
}
err = ctx.Err()
if err != nil {
err = fmt.Errorf("horizon: context error: %w", err)
}
return
}
//func setPixel(pixel *tengo.Array, i int, x int64) {
// v := pixel.Value[i].(*tengo.Int)
// v.Value = x
//}
func getPixel(pixel *tengo.Array, i int) int64 {
v := pixel.Value[i].(*tengo.Int)
return v.Value
}