func (s Selection) Selection(localX, localY int) Selection {
	return Selection{
		x:     localX + s.x,
		y:     localY + s.y,
		image: s.image,
	}
}
Selection makes a new selection using the coordinates of existing selection.
Passed coordinates are local, which means that the top-left corner of existing
selection is equivalent to localX=0, localY=0. Both coordinates can be negative,
meaning that selection starts outside the original selection.
package image
type AcceleratedImage interface {
	Upload(pixels []Color)
	Download(output []Color)
	Width() int
	Height() int
	Delete()
}
func New(acceleratedImage AcceleratedImage) *Image {
	if acceleratedImage == nil {
		panic("nil acceleratedImage")
	}
	width := acceleratedImage.Width()
	height := acceleratedImage.Height()
	if width < 0 {
		panic("negative width")
	}
	if height < 0 {
		panic("negative height")
	}
	return &Image{
		width:            width,
		height:           height,
		heightMinusOne:   height - 1,
		pixels:           make([]Color, width*height),
		acceleratedImage: acceleratedImage,
		selectionsCache:  make([]AcceleratedImageSelection, 0, 4),
	}
}
type Image struct {
	width          int
	height         int
	heightMinusOne int
	pixels                   []Color
	acceleratedImage         AcceleratedImage
	selectionsCache          []AcceleratedImageSelection
	acceleratedImageModified bool
	ramModified              bool
}
func (i *Image) Width() int {
	return i.width
}
func (i *Image) Height() int {
	return i.height
}
func (i *Image) Selection(x int, y int) Selection {
	return Selection{
		x:     x,
		y:     y,
		image: i,
	}
}
func (i *Image) WholeImageSelection() Selection {
	return i.Selection(0, 0).WithSize(i.width, i.height)
}
func (i *Image) Upload() {
	if i.ramModified {
		i.acceleratedImage.Upload(i.pixels)
		i.ramModified = false
	}
}
func (i *Image) Delete() {
	i.acceleratedImage.Delete()
}
type Selection struct {
	image         *Image
	x, y          int
	width, height int
}
func (s Selection) Image() *Image {
	return s.image
}
func (s Selection) Width() int {
	return s.width
}
func (s Selection) Height() int {
	return s.height
}
func (s Selection) ImageX() int {
	return s.x
}
func (s Selection) ImageY() int {
	return s.y
}
func (s Selection) WithSize(width, height int) Selection {
	if width > 0 {
		s.width = width
	} else {
		s.width = 0
	}
	if height > 0 {
		s.height = height
	} else {
		s.height = 0
	}
	return s
}