The WebAssembly version of AutoDistortion (https://github.com/pommicket/autodistortion)
/* | |
Copyright (C) 2019 Leo Tenenbaum | |
This file is part of AutoDistortion. | |
AutoDistortion is free software: you can redistribute it and/or modify | |
it under the terms of the GNU General Public License as published by | |
the Free Software Foundation, either version 3 of the License, or | |
(at your option) any later version. | |
AutoDistortion is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU General Public License for more details. | |
You should have received a copy of the GNU General Public License | |
along with AutoDistortion. If not, see <https://www.gnu.org/licenses/>. | |
*/ | |
package main | |
import ( | |
"syscall/js" | |
"image" | |
"image/color" | |
"math/rand" | |
"time" | |
"github.com/pommicket/autodistortion/autoutils" | |
"github.com/pommicket/autodistortion/autodistortion" | |
) | |
type jsImage struct { | |
data js.Value | |
width int | |
height int | |
} | |
func (img *jsImage) ColorModel() color.Model { | |
return color.RGBAModel | |
} | |
func (img *jsImage) Bounds() image.Rectangle { | |
return image.Rectangle{image.Point{0, 0}, image.Point{img.width, img.height}} | |
} | |
func (img *jsImage) At(x, y int) color.Color { | |
i := (img.width * y + x) * 4 | |
return color.RGBA{uint8(img.data.Index(i).Int()), | |
uint8(img.data.Index(i+1).Int()), | |
uint8(img.data.Index(i+2).Int()), | |
uint8(img.data.Index(i+3).Int())} | |
} | |
func distort(this js.Value, args []js.Value) interface{} { | |
width := args[1].Int() | |
height := args[2].Int() | |
output := args[3] | |
fLength := args[4].Int() | |
seed := int64(args[5].Int()) | |
if seed == -1 { | |
seed = time.Now().UTC().UnixNano() | |
} | |
rand.Seed(seed) | |
img := jsImage{args[0], width, height} | |
var xfunction, yfunction autoutils.Function | |
xfunction.Generate(2, fLength) | |
yfunction.Generate(2, fLength) | |
winfo := autodistortion.WorkInfo{&img, xfunction, yfunction} | |
pixels := make([][]color.RGBA, height) | |
for y := 0; y < height; y++ { | |
pixels[y] = make([]color.RGBA, width) | |
} | |
nThreads := 64 | |
if nThreads > height { | |
nThreads = height | |
} | |
done := make(chan struct{}) | |
for thread := 0; thread < nThreads; thread++ { | |
minY := thread * (height / nThreads) | |
var maxY int | |
if thread == nThreads - 1 { | |
maxY = height | |
} else { | |
maxY = (thread+1) * (height / nThreads) | |
} | |
go autodistortion.DistortRows(&winfo, pixels, minY, maxY, done) | |
} | |
// Wait for threads to finish | |
for thread := 0; thread < nThreads; thread++ { | |
<-done | |
} | |
// convert to array of ints | |
for y := 0; y < height; y++ { | |
for x := 0; x < width; x++ { | |
i := 4 * (y * width + x) | |
output.SetIndex(i+0, pixels[y][x].R) | |
output.SetIndex(i+1, pixels[y][x].G) | |
output.SetIndex(i+2, pixels[y][x].B) | |
output.SetIndex(i+3, pixels[y][x].A) | |
} | |
} | |
return 0 | |
} | |
func main() { | |
c := make(chan struct{}, 0) | |
js.Global().Set("distort", js.FuncOf(distort)) | |
<-c | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment