Skip to content

Instantly share code, notes, and snippets.

@pommicket
Created June 11, 2019 01:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pommicket/b79b79480ca3e27b4f73ab316986e7a9 to your computer and use it in GitHub Desktop.
Save pommicket/b79b79480ca3e27b4f73ab316986e7a9 to your computer and use it in GitHub Desktop.
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