Avoid temporaries to save some cycles.
This commit is contained in:
parent
7c5018c82b
commit
314cea6612
80
converter.go
80
converter.go
|
@ -43,94 +43,88 @@ func replicateBorder(x, y int, rect image.Rectangle) (xx, yy int) {
|
||||||
// the idea is to speed up computation by providing optimized implementations
|
// the idea is to speed up computation by providing optimized implementations
|
||||||
// for different image types instead of relying on image.Image.At().
|
// for different image types instead of relying on image.Image.At().
|
||||||
type converter interface {
|
type converter interface {
|
||||||
at(x, y int) colorArray
|
at(x, y int, color *colorArray)
|
||||||
}
|
}
|
||||||
|
|
||||||
type genericConverter struct {
|
type genericConverter struct {
|
||||||
src image.Image
|
src image.Image
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *genericConverter) at(x, y int) colorArray {
|
func (c *genericConverter) at(x, y int, result *colorArray) {
|
||||||
r, g, b, a := c.src.At(replicateBorder(x, y, c.src.Bounds())).RGBA()
|
r, g, b, a := c.src.At(replicateBorder(x, y, c.src.Bounds())).RGBA()
|
||||||
return colorArray{
|
result[0] = float32(r)
|
||||||
float32(r),
|
result[1] = float32(g)
|
||||||
float32(g),
|
result[2] = float32(b)
|
||||||
float32(b),
|
result[3] = float32(a)
|
||||||
float32(a),
|
return
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type rgbaConverter struct {
|
type rgbaConverter struct {
|
||||||
src *image.RGBA
|
src *image.RGBA
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *rgbaConverter) at(x, y int) colorArray {
|
func (c *rgbaConverter) at(x, y int, result *colorArray) {
|
||||||
i := c.src.PixOffset(replicateBorder(x, y, c.src.Rect))
|
i := c.src.PixOffset(replicateBorder(x, y, c.src.Rect))
|
||||||
return colorArray{
|
result[0] = float32(uint16(c.src.Pix[i+0])<<8 | uint16(c.src.Pix[i+0]))
|
||||||
float32(uint16(c.src.Pix[i+0])<<8 | uint16(c.src.Pix[i+0])),
|
result[1] = float32(uint16(c.src.Pix[i+1])<<8 | uint16(c.src.Pix[i+1]))
|
||||||
float32(uint16(c.src.Pix[i+1])<<8 | uint16(c.src.Pix[i+1])),
|
result[2] = float32(uint16(c.src.Pix[i+2])<<8 | uint16(c.src.Pix[i+2]))
|
||||||
float32(uint16(c.src.Pix[i+2])<<8 | uint16(c.src.Pix[i+2])),
|
result[3] = float32(uint16(c.src.Pix[i+3])<<8 | uint16(c.src.Pix[i+3]))
|
||||||
float32(uint16(c.src.Pix[i+3])<<8 | uint16(c.src.Pix[i+3])),
|
return
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type rgba64Converter struct {
|
type rgba64Converter struct {
|
||||||
src *image.RGBA64
|
src *image.RGBA64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *rgba64Converter) at(x, y int) colorArray {
|
func (c *rgba64Converter) at(x, y int, result *colorArray) {
|
||||||
i := c.src.PixOffset(replicateBorder(x, y, c.src.Rect))
|
i := c.src.PixOffset(replicateBorder(x, y, c.src.Rect))
|
||||||
return colorArray{
|
result[0] = float32(uint16(c.src.Pix[i+0])<<8 | uint16(c.src.Pix[i+1]))
|
||||||
float32(uint16(c.src.Pix[i+0])<<8 | uint16(c.src.Pix[i+1])),
|
result[1] = float32(uint16(c.src.Pix[i+2])<<8 | uint16(c.src.Pix[i+3]))
|
||||||
float32(uint16(c.src.Pix[i+2])<<8 | uint16(c.src.Pix[i+3])),
|
result[2] = float32(uint16(c.src.Pix[i+4])<<8 | uint16(c.src.Pix[i+5]))
|
||||||
float32(uint16(c.src.Pix[i+4])<<8 | uint16(c.src.Pix[i+5])),
|
result[3] = float32(uint16(c.src.Pix[i+6])<<8 | uint16(c.src.Pix[i+7]))
|
||||||
float32(uint16(c.src.Pix[i+6])<<8 | uint16(c.src.Pix[i+7])),
|
return
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type grayConverter struct {
|
type grayConverter struct {
|
||||||
src *image.Gray
|
src *image.Gray
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *grayConverter) at(x, y int) colorArray {
|
func (c *grayConverter) at(x, y int, result *colorArray) {
|
||||||
i := c.src.PixOffset(replicateBorder(x, y, c.src.Rect))
|
i := c.src.PixOffset(replicateBorder(x, y, c.src.Rect))
|
||||||
g := float32(uint16(c.src.Pix[i])<<8 | uint16(c.src.Pix[i]))
|
g := float32(uint16(c.src.Pix[i])<<8 | uint16(c.src.Pix[i]))
|
||||||
return colorArray{
|
result[0] = g
|
||||||
g,
|
result[1] = g
|
||||||
g,
|
result[2] = g
|
||||||
g,
|
result[3] = float32(0xffff)
|
||||||
float32(0xffff),
|
return
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type gray16Converter struct {
|
type gray16Converter struct {
|
||||||
src *image.Gray16
|
src *image.Gray16
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *gray16Converter) at(x, y int) colorArray {
|
func (c *gray16Converter) at(x, y int, result *colorArray) {
|
||||||
i := c.src.PixOffset(replicateBorder(x, y, c.src.Rect))
|
i := c.src.PixOffset(replicateBorder(x, y, c.src.Rect))
|
||||||
g := float32(uint16(c.src.Pix[i+0])<<8 | uint16(c.src.Pix[i+1]))
|
g := float32(uint16(c.src.Pix[i+0])<<8 | uint16(c.src.Pix[i+1]))
|
||||||
return colorArray{
|
result[0] = g
|
||||||
g,
|
result[1] = g
|
||||||
g,
|
result[2] = g
|
||||||
g,
|
result[3] = float32(0xffff)
|
||||||
float32(0xffff),
|
return
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ycbcrConverter struct {
|
type ycbcrConverter struct {
|
||||||
src *image.YCbCr
|
src *image.YCbCr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ycbcrConverter) at(x, y int) colorArray {
|
func (c *ycbcrConverter) at(x, y int, result *colorArray) {
|
||||||
xx, yy := replicateBorder(x, y, c.src.Rect)
|
xx, yy := replicateBorder(x, y, c.src.Rect)
|
||||||
yi := c.src.YOffset(xx, yy)
|
yi := c.src.YOffset(xx, yy)
|
||||||
ci := c.src.COffset(xx, yy)
|
ci := c.src.COffset(xx, yy)
|
||||||
r, g, b := color.YCbCrToRGB(c.src.Y[yi], c.src.Cb[ci], c.src.Cr[ci])
|
r, g, b := color.YCbCrToRGB(c.src.Y[yi], c.src.Cb[ci], c.src.Cr[ci])
|
||||||
return colorArray{
|
result[0] = float32(uint16(r) * 0x101)
|
||||||
float32(uint16(r) * 0x101),
|
result[1] = float32(uint16(g) * 0x101)
|
||||||
float32(uint16(g) * 0x101),
|
result[2] = float32(uint16(b) * 0x101)
|
||||||
float32(uint16(b) * 0x101),
|
result[3] = float32(0xffff)
|
||||||
float32(0xffff),
|
return
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,10 +51,9 @@ type filterModel struct {
|
||||||
tempRow []colorArray
|
tempRow []colorArray
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *filterModel) convolution1d(x float32, p []colorArray, factor float32) colorArray {
|
func (f *filterModel) convolution1d(x float32, p []colorArray, factor float32) (c colorArray) {
|
||||||
var k float32
|
var k float32
|
||||||
var sum float32 = 0
|
var sum float32 = 0
|
||||||
c := colorArray{0.0, 0.0, 0.0, 0.0}
|
|
||||||
|
|
||||||
for j := range p {
|
for j := range p {
|
||||||
k = f.kernel((x - float32(j)) / factor)
|
k = f.kernel((x - float32(j)) / factor)
|
||||||
|
@ -69,7 +68,7 @@ func (f *filterModel) convolution1d(x float32, p []colorArray, factor float32) c
|
||||||
c[i] = c[i] / sum
|
c[i] = c[i] / sum
|
||||||
}
|
}
|
||||||
|
|
||||||
return c
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *filterModel) Interpolate(u float32, y int) color.RGBA64 {
|
func (f *filterModel) Interpolate(u float32, y int) color.RGBA64 {
|
||||||
|
@ -77,7 +76,7 @@ func (f *filterModel) Interpolate(u float32, y int) color.RGBA64 {
|
||||||
u -= float32(uf)
|
u -= float32(uf)
|
||||||
|
|
||||||
for i := range f.tempRow {
|
for i := range f.tempRow {
|
||||||
f.tempRow[i] = f.at(uf+i, y)
|
f.at(uf+i, y, &f.tempRow[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
c := f.convolution1d(u, f.tempRow, f.factor)
|
c := f.convolution1d(u, f.tempRow, f.factor)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user