func (p *XYZ64) SetXYZ(x, y int, c hdrcolor.XYZ) {
	if !(image.Point{x, y}.In(p.Rect)) {
		return
	}
	i := p.PixOffset(x, y)
	p.Pix[i+0] = c.X
	p.Pix[i+1] = c.Y
	p.Pix[i+2] = c.Z
}
SetXYZ applies the given XYZ color at this coordinate.
package hdr
import (
	"image"
	"image/color"
	"github.com/mdouchement/hdr/hdrcolor"
)
type Image interface {
	image.Image
	HDRAt(x, y int) hdrcolor.Color
	Size() int
}
type ImageSet interface {
	Set(x, y int, c color.Color)
}
func EmptyAs(src Image) Image {
	switch m := src.(type) {
	case *RGB:
		return NewRGB(m.Bounds())
	case *RGB64:
		return NewRGB64(m.Bounds())
	case *XYZ:
		return NewXYZ(m.Bounds())
	case *XYZ64:
		return NewXYZ64(m.Bounds())
	default:
		return NewRGB64(m.Bounds())
	}
}
func Copy(src Image) Image {
	switch m := src.(type) {
	case *RGB:
		dst := NewRGB(m.Bounds())
		copy(dst.Pix, m.Pix)
		return dst
	case *RGB64:
		dst := NewRGB64(m.Bounds())
		copy(dst.Pix, m.Pix)
		return dst
	case *XYZ:
		dst := NewXYZ(m.Bounds())
		copy(dst.Pix, m.Pix)
		return dst
	case *XYZ64:
		dst := NewXYZ64(m.Bounds())
		copy(dst.Pix, m.Pix)
		return dst
	default:
		dst := NewRGB64(m.Bounds())
		for y := 0; y < m.Bounds().Dy(); y++ {
			for x := 0; x < m.Bounds().Dx(); x++ {
				dst.Set(x, y, src.HDRAt(x, y))
			}
		}
		return dst
	}
}
type RGB struct {
	Pix []float32
	Stride int
	Rect image.Rectangle
}
func NewRGB(r image.Rectangle) *RGB {
	w, h := r.Dx(), r.Dy()
	buf := make([]float32, 3*w*h)
	return &RGB{buf, 3 * w, r}
}
func (p *RGB) ColorModel() color.Model { return hdrcolor.RGBModel }
func (p *RGB) Bounds() image.Rectangle { return p.Rect }
func (p *RGB) Size() int {
	return p.Bounds().Dx() * p.Bounds().Dy()
}
func (p *RGB) At(x, y int) color.Color {
	return p.RGBAt(x, y)
}
func (p *RGB) HDRAt(x, y int) hdrcolor.Color {
	return p.RGBAt(x, y)
}
func (p *RGB) RGBAt(x, y int) hdrcolor.RGB {
	if !(image.Point{x, y}.In(p.Rect)) {
		return hdrcolor.RGB{}
	}
	i := p.PixOffset(x, y)
	return hdrcolor.RGB{
		R: float64(p.Pix[i+0]),
		G: float64(p.Pix[i+1]),
		B: float64(p.Pix[i+2]),
	}
}
func (p *RGB) PixOffset(x, y int) int {
	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*3
}
func (p *RGB) Set(x, y int, c color.Color) {
	if !(image.Point{x, y}.In(p.Rect)) {
		return
	}
	i := p.PixOffset(x, y)
	c1 := hdrcolor.RGBModel.Convert(c).(hdrcolor.RGB)
	p.Pix[i+0] = float32(c1.R)
	p.Pix[i+1] = float32(c1.G)
	p.Pix[i+2] = float32(c1.B)
}
func (p *RGB) SetRGB(x, y int, c hdrcolor.RGB) {
	if !(image.Point{x, y}.In(p.Rect)) {
		return
	}
	i := p.PixOffset(x, y)
	p.Pix[i+0] = float32(c.R)
	p.Pix[i+1] = float32(c.G)
	p.Pix[i+2] = float32(c.B)
}
type RGB64 struct {
	Pix []float64
	Stride int
	Rect image.Rectangle
}
func NewRGB64(r image.Rectangle) *RGB64 {
	w, h := r.Dx(), r.Dy()
	buf := make([]float64, 3*w*h)
	return &RGB64{buf, 3 * w, r}
}
func (p *RGB64) ColorModel() color.Model { return hdrcolor.RGBModel }
func (p *RGB64) Bounds() image.Rectangle { return p.Rect }
func (p *RGB64) Size() int {
	return p.Bounds().Dx() * p.Bounds().Dy()
}
func (p *RGB64) At(x, y int) color.Color {
	return p.RGBAt(x, y)
}
func (p *RGB64) HDRAt(x, y int) hdrcolor.Color {
	return p.RGBAt(x, y)
}
func (p *RGB64) RGBAt(x, y int) hdrcolor.RGB {
	if !(image.Point{x, y}.In(p.Rect)) {
		return hdrcolor.RGB{}
	}
	i := p.PixOffset(x, y)
	return hdrcolor.RGB{R: p.Pix[i+0], G: p.Pix[i+1], B: p.Pix[i+2]}
}
func (p *RGB64) PixOffset(x, y int) int {
	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*3
}
func (p *RGB64) Set(x, y int, c color.Color) {
	if !(image.Point{x, y}.In(p.Rect)) {
		return
	}
	i := p.PixOffset(x, y)
	c1 := hdrcolor.RGBModel.Convert(c).(hdrcolor.RGB)
	p.Pix[i+0] = c1.R
	p.Pix[i+1] = c1.G
	p.Pix[i+2] = c1.B
}
func (p *RGB64) SetRGB(x, y int, c hdrcolor.RGB) {
	if !(image.Point{x, y}.In(p.Rect)) {
		return
	}
	i := p.PixOffset(x, y)
	p.Pix[i+0] = c.R
	p.Pix[i+1] = c.G
	p.Pix[i+2] = c.B
}
type XYZ struct {
	Pix []float32
	Stride int
	Rect image.Rectangle
}
func NewXYZ(r image.Rectangle) *XYZ {
	w, h := r.Dx(), r.Dy()
	buf := make([]float32, 3*w*h)
	return &XYZ{buf, 3 * w, r}
}
func (p *XYZ) ColorModel() color.Model { return hdrcolor.XYZModel }
func (p *XYZ) Bounds() image.Rectangle { return p.Rect }
func (p *XYZ) Size() int {
	return p.Bounds().Dx() * p.Bounds().Dy()
}
func (p *XYZ) At(x, y int) color.Color {
	return p.XYZAt(x, y)
}
func (p *XYZ) HDRAt(x, y int) hdrcolor.Color {
	return p.XYZAt(x, y)
}
func (p *XYZ) XYZAt(x, y int) hdrcolor.XYZ {
	if !(image.Point{x, y}.In(p.Rect)) {
		return hdrcolor.XYZ{}
	}
	i := p.PixOffset(x, y)
	return hdrcolor.XYZ{
		X: float64(p.Pix[i+0]),
		Y: float64(p.Pix[i+1]),
		Z: float64(p.Pix[i+2]),
	}
}
func (p *XYZ) PixOffset(x, y int) int {
	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*3
}
func (p *XYZ) Set(x, y int, c color.Color) {
	if !(image.Point{x, y}.In(p.Rect)) {
		return
	}
	i := p.PixOffset(x, y)
	c1 := hdrcolor.XYZModel.Convert(c).(hdrcolor.XYZ)
	p.Pix[i+0] = float32(c1.X)
	p.Pix[i+1] = float32(c1.Y)
	p.Pix[i+2] = float32(c1.Z)
}
func (p *XYZ) SetXYZ(x, y int, c hdrcolor.XYZ) {
	if !(image.Point{x, y}.In(p.Rect)) {
		return
	}
	i := p.PixOffset(x, y)
	p.Pix[i+0] = float32(c.X)
	p.Pix[i+1] = float32(c.Y)
	p.Pix[i+2] = float32(c.Z)
}
type XYZ64 struct {
	Pix []float64
	Stride int
	Rect image.Rectangle
}
func NewXYZ64(r image.Rectangle) *XYZ64 {
	w, h := r.Dx(), r.Dy()
	buf := make([]float64, 3*w*h)
	return &XYZ64{buf, 3 * w, r}
}
func (p *XYZ64) ColorModel() color.Model { return hdrcolor.XYZModel }
func (p *XYZ64) Bounds() image.Rectangle { return p.Rect }
func (p *XYZ64) Size() int {
	return p.Bounds().Dx() * p.Bounds().Dy()
}
func (p *XYZ64) At(x, y int) color.Color {
	return p.XYZAt(x, y)
}
func (p *XYZ64) HDRAt(x, y int) hdrcolor.Color {
	return p.XYZAt(x, y)
}
func (p *XYZ64) XYZAt(x, y int) hdrcolor.XYZ {
	if !(image.Point{x, y}.In(p.Rect)) {
		return hdrcolor.XYZ{}
	}
	i := p.PixOffset(x, y)
	return hdrcolor.XYZ{X: p.Pix[i+0], Y: p.Pix[i+1], Z: p.Pix[i+2]}
}
func (p *XYZ64) PixOffset(x, y int) int {
	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*3
}
func (p *XYZ64) Set(x, y int, c color.Color) {
	if !(image.Point{x, y}.In(p.Rect)) {
		return
	}
	i := p.PixOffset(x, y)
	c1 := hdrcolor.XYZModel.Convert(c).(hdrcolor.XYZ)
	p.Pix[i+0] = c1.X
	p.Pix[i+1] = c1.Y
	p.Pix[i+2] = c1.Z
}