blooblib/draw_image.go

163 lines
4.7 KiB
Go

package bloob
func (image *Image) Draw(other *Image, dst Vec2i) {
image.DrawSub(other, dst, Recti{Size: other.Size})
}
func (image *Image) DrawSub(other *Image, pos Vec2i, rect Recti) {
start, end, dst := CropToArea(image.Size, rect, pos)
//println(start.X, "|", end.X, "|", dst.X, "|", pos.X)
//println(end.Y)
if other.Alpha {
for y := start.Y; y < end.Y; y += 1 {
for x := start.X; x < end.X; x += 1 {
//println(y)
val := other.Data[x+y*other.Size.X]
if val&0xff000000 > 0 {
image.Data[(x+dst.X)+(y+dst.Y)*image.Size.X] = val
}
}
}
} else {
for y := start.Y; y < end.Y; y += 1 {
for x := start.X; x < end.X; x += 1 {
image.Data[(x+dst.X)+(y+dst.Y)*image.Size.X] = other.Data[x+y*other.Size.X]
}
}
}
}
func (image *Image) DrawColor(other *Image, dst Vec2i, color Color) {
image.DrawSubColor(other, dst, Recti{Size: other.Size}, color)
}
func (image *Image) DrawSubColor(other *Image, pos Vec2i, rect Recti, color Color) {
start, end, dst := CropToArea(image.Size, rect, pos)
for y := start.Y; y < end.Y; y += 1 {
for x := start.X; x < end.X; x += 1 {
//println(y)
val := other.Data[x+y*other.Size.X]
if val&0xff000000 > 0 {
image.Data[(x+dst.X)+(y+dst.Y)*image.Size.X] = color
}
}
}
}
func (image *Image) DrawUpscale(other *Image) {
var scale int
if image.Size.X/other.Size.X < image.Size.Y/other.Size.Y {
scale = image.Size.X / other.Size.X
} else {
scale = image.Size.Y / other.Size.Y
}
switch scale {
case 1:
wg.Add(other.Size.Y)
for y := 0; y < other.Size.Y; y += 1 {
go func(image, other *Image, y int) {
defer wg.Done()
for x := 0; x < other.Size.X; x += 1 {
val := other.Data[x+y*other.Size.X]
image.Data[(x*scale)+(y*scale)*image.Size.X] = val
}
}(image, other, y)
}
wg.Wait()
break
case 2:
wg.Add(other.Size.Y)
for y := 0; y < other.Size.Y; y += 1 {
go func(image, other *Image, y int) {
defer wg.Done()
for x := 0; x < other.Size.X; x += 1 {
val := other.Data[x+y*other.Size.X]
val2 := (val & 0xfefefe) >> 1
dx := x * 2
dy := y * 2
image.Data[(dx+0)+(dy+0)*image.Size.X] = val
image.Data[(dx+1)+(dy+0)*image.Size.X] = val
image.Data[(dx+0)+(dy+1)*image.Size.X] = val2
image.Data[(dx+1)+(dy+1)*image.Size.X] = val2
}
}(image, other, y)
}
wg.Wait()
break
case 3:
wg.Add(other.Size.Y)
//println("Before thread count : ", threadProfile.Count())
for y := 0; y < other.Size.Y; y += 1 {
go func(image, other *Image, y int) {
defer wg.Done()
for x := 0; x < other.Size.X; x += 1 {
val := other.Data[x+y*other.Size.X]
val2 := (val & 0xfefefe) >> 1
dx := x * 3
dy := y * 3
image.Data[(dx+0)+(dy+0)*image.Size.X] = val
image.Data[(dx+1)+(dy+0)*image.Size.X] = val
image.Data[(dx+2)+(dy+0)*image.Size.X] = val2
image.Data[(dx+0)+(dy+1)*image.Size.X] = val
image.Data[(dx+1)+(dy+1)*image.Size.X] = val
image.Data[(dx+2)+(dy+1)*image.Size.X] = val2
image.Data[(dx+0)+(dy+2)*image.Size.X] = val2
image.Data[(dx+1)+(dy+2)*image.Size.X] = val2
image.Data[(dx+2)+(dy+2)*image.Size.X] = val2
}
}(image, other, y)
}
//println("After thread count : ", threadProfile.Count())
wg.Wait()
break
case 4:
wg.Add(other.Size.Y)
for y := 0; y < other.Size.Y; y += 1 {
go func(image, other *Image, y int) {
defer wg.Done()
for x := 0; x < other.Size.X; x += 1 {
val := other.Data[x+y*other.Size.X]
dx := x * 4
dy := y * 4
image.Data[(dx+0)+(dy+0)*image.Size.X] = val
image.Data[(dx+1)+(dy+0)*image.Size.X] = val
image.Data[(dx+2)+(dy+0)*image.Size.X] = val
image.Data[(dx+3)+(dy+0)*image.Size.X] = val
image.Data[(dx+0)+(dy+1)*image.Size.X] = val
image.Data[(dx+1)+(dy+1)*image.Size.X] = val
image.Data[(dx+2)+(dy+1)*image.Size.X] = val
image.Data[(dx+3)+(dy+1)*image.Size.X] = val
image.Data[(dx+0)+(dy+2)*image.Size.X] = val
image.Data[(dx+1)+(dy+2)*image.Size.X] = val
image.Data[(dx+2)+(dy+2)*image.Size.X] = val
image.Data[(dx+3)+(dy+2)*image.Size.X] = val
image.Data[(dx+0)+(dy+3)*image.Size.X] = val
image.Data[(dx+1)+(dy+3)*image.Size.X] = val
image.Data[(dx+2)+(dy+3)*image.Size.X] = val
image.Data[(dx+3)+(dy+3)*image.Size.X] = val
}
}(image, other, y)
}
wg.Wait()
break
default:
wg.Add(other.Size.Y)
for y := 0; y < other.Size.Y; y += 1 {
go func(image, other *Image, y int) {
defer wg.Done()
for x := 0; x < other.Size.X; x += 1 {
val := other.Data[x+y*other.Size.X]
for sy := 0; sy < scale; sy += 1 {
for sx := 0; sx < scale; sx += 1 {
image.Data[(x*scale+sx)+(y*scale+sy)*image.Size.X] = val
}
}
}
}(image, other, y)
}
wg.Wait()
break
}
}