summaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp
diff options
context:
space:
mode:
authorhmhealey <harrisonmhealey@gmail.com>2015-09-17 11:08:47 -0400
committerhmhealey <harrisonmhealey@gmail.com>2015-09-17 19:13:42 -0400
commitd83be6df2d8b0e2fef4cb6866cfdb6434bbef5c4 (patch)
treea4677163f2aa762c75988fe402b9aea89d95e0be /Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp
parent82127341cacd4299f9a59e76b5f68d6d7222c45b (diff)
downloadchat-d83be6df2d8b0e2fef4cb6866cfdb6434bbef5c4.tar.gz
chat-d83be6df2d8b0e2fef4cb6866cfdb6434bbef5c4.tar.bz2
chat-d83be6df2d8b0e2fef4cb6866cfdb6434bbef5c4.zip
PLT-173 Added graphics-go and goexif libraries for image manipulation
Diffstat (limited to 'Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp')
-rw-r--r--Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/Makefile13
-rw-r--r--Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/bilinear.go206
-rw-r--r--Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/bilinear_test.go143
-rw-r--r--Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/doc.go25
-rw-r--r--Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/interp.go29
5 files changed, 416 insertions, 0 deletions
diff --git a/Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/Makefile b/Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/Makefile
new file mode 100644
index 000000000..4d8f524fb
--- /dev/null
+++ b/Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/Makefile
@@ -0,0 +1,13 @@
+# Copyright 2012 The Graphics-Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+include $(GOROOT)/src/Make.inc
+
+TARG=code.google.com/p/graphics-go/graphics/interp
+GOFILES=\
+ bilinear.go\
+ doc.go\
+ interp.go\
+
+include $(GOROOT)/src/Make.pkg
diff --git a/Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/bilinear.go b/Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/bilinear.go
new file mode 100644
index 000000000..e18321a15
--- /dev/null
+++ b/Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/bilinear.go
@@ -0,0 +1,206 @@
+// Copyright 2012 The Graphics-Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package interp
+
+import (
+ "image"
+ "image/color"
+ "math"
+)
+
+// Bilinear implements bilinear interpolation.
+var Bilinear Interp = bilinear{}
+
+type bilinear struct{}
+
+func (i bilinear) Interp(src image.Image, x, y float64) color.Color {
+ if src, ok := src.(*image.RGBA); ok {
+ return i.RGBA(src, x, y)
+ }
+ return bilinearGeneral(src, x, y)
+}
+
+func bilinearGeneral(src image.Image, x, y float64) color.Color {
+ p := findLinearSrc(src.Bounds(), x, y)
+ var fr, fg, fb, fa float64
+ var r, g, b, a uint32
+
+ r, g, b, a = src.At(p.low.X, p.low.Y).RGBA()
+ fr += float64(r) * p.frac00
+ fg += float64(g) * p.frac00
+ fb += float64(b) * p.frac00
+ fa += float64(a) * p.frac00
+
+ r, g, b, a = src.At(p.high.X, p.low.Y).RGBA()
+ fr += float64(r) * p.frac01
+ fg += float64(g) * p.frac01
+ fb += float64(b) * p.frac01
+ fa += float64(a) * p.frac01
+
+ r, g, b, a = src.At(p.low.X, p.high.Y).RGBA()
+ fr += float64(r) * p.frac10
+ fg += float64(g) * p.frac10
+ fb += float64(b) * p.frac10
+ fa += float64(a) * p.frac10
+
+ r, g, b, a = src.At(p.high.X, p.high.Y).RGBA()
+ fr += float64(r) * p.frac11
+ fg += float64(g) * p.frac11
+ fb += float64(b) * p.frac11
+ fa += float64(a) * p.frac11
+
+ var c color.RGBA64
+ c.R = uint16(fr + 0.5)
+ c.G = uint16(fg + 0.5)
+ c.B = uint16(fb + 0.5)
+ c.A = uint16(fa + 0.5)
+ return c
+}
+
+func (bilinear) RGBA(src *image.RGBA, x, y float64) color.RGBA {
+ p := findLinearSrc(src.Bounds(), x, y)
+
+ // Array offsets for the surrounding pixels.
+ off00 := offRGBA(src, p.low.X, p.low.Y)
+ off01 := offRGBA(src, p.high.X, p.low.Y)
+ off10 := offRGBA(src, p.low.X, p.high.Y)
+ off11 := offRGBA(src, p.high.X, p.high.Y)
+
+ var fr, fg, fb, fa float64
+
+ fr += float64(src.Pix[off00+0]) * p.frac00
+ fg += float64(src.Pix[off00+1]) * p.frac00
+ fb += float64(src.Pix[off00+2]) * p.frac00
+ fa += float64(src.Pix[off00+3]) * p.frac00
+
+ fr += float64(src.Pix[off01+0]) * p.frac01
+ fg += float64(src.Pix[off01+1]) * p.frac01
+ fb += float64(src.Pix[off01+2]) * p.frac01
+ fa += float64(src.Pix[off01+3]) * p.frac01
+
+ fr += float64(src.Pix[off10+0]) * p.frac10
+ fg += float64(src.Pix[off10+1]) * p.frac10
+ fb += float64(src.Pix[off10+2]) * p.frac10
+ fa += float64(src.Pix[off10+3]) * p.frac10
+
+ fr += float64(src.Pix[off11+0]) * p.frac11
+ fg += float64(src.Pix[off11+1]) * p.frac11
+ fb += float64(src.Pix[off11+2]) * p.frac11
+ fa += float64(src.Pix[off11+3]) * p.frac11
+
+ var c color.RGBA
+ c.R = uint8(fr + 0.5)
+ c.G = uint8(fg + 0.5)
+ c.B = uint8(fb + 0.5)
+ c.A = uint8(fa + 0.5)
+ return c
+}
+
+func (bilinear) Gray(src *image.Gray, x, y float64) color.Gray {
+ p := findLinearSrc(src.Bounds(), x, y)
+
+ // Array offsets for the surrounding pixels.
+ off00 := offGray(src, p.low.X, p.low.Y)
+ off01 := offGray(src, p.high.X, p.low.Y)
+ off10 := offGray(src, p.low.X, p.high.Y)
+ off11 := offGray(src, p.high.X, p.high.Y)
+
+ var fc float64
+ fc += float64(src.Pix[off00]) * p.frac00
+ fc += float64(src.Pix[off01]) * p.frac01
+ fc += float64(src.Pix[off10]) * p.frac10
+ fc += float64(src.Pix[off11]) * p.frac11
+
+ var c color.Gray
+ c.Y = uint8(fc + 0.5)
+ return c
+}
+
+type bilinearSrc struct {
+ // Top-left and bottom-right interpolation sources
+ low, high image.Point
+ // Fraction of each pixel to take. The 0 suffix indicates
+ // top/left, and the 1 suffix indicates bottom/right.
+ frac00, frac01, frac10, frac11 float64
+}
+
+func findLinearSrc(b image.Rectangle, sx, sy float64) bilinearSrc {
+ maxX := float64(b.Max.X)
+ maxY := float64(b.Max.Y)
+ minX := float64(b.Min.X)
+ minY := float64(b.Min.Y)
+ lowX := math.Floor(sx - 0.5)
+ lowY := math.Floor(sy - 0.5)
+ if lowX < minX {
+ lowX = minX
+ }
+ if lowY < minY {
+ lowY = minY
+ }
+
+ highX := math.Ceil(sx - 0.5)
+ highY := math.Ceil(sy - 0.5)
+ if highX >= maxX {
+ highX = maxX - 1
+ }
+ if highY >= maxY {
+ highY = maxY - 1
+ }
+
+ // In the variables below, the 0 suffix indicates top/left, and the
+ // 1 suffix indicates bottom/right.
+
+ // Center of each surrounding pixel.
+ x00 := lowX + 0.5
+ y00 := lowY + 0.5
+ x01 := highX + 0.5
+ y01 := lowY + 0.5
+ x10 := lowX + 0.5
+ y10 := highY + 0.5
+ x11 := highX + 0.5
+ y11 := highY + 0.5
+
+ p := bilinearSrc{
+ low: image.Pt(int(lowX), int(lowY)),
+ high: image.Pt(int(highX), int(highY)),
+ }
+
+ // Literally, edge cases. If we are close enough to the edge of
+ // the image, curtail the interpolation sources.
+ if lowX == highX && lowY == highY {
+ p.frac00 = 1.0
+ } else if sy-minY <= 0.5 && sx-minX <= 0.5 {
+ p.frac00 = 1.0
+ } else if maxY-sy <= 0.5 && maxX-sx <= 0.5 {
+ p.frac11 = 1.0
+ } else if sy-minY <= 0.5 || lowY == highY {
+ p.frac00 = x01 - sx
+ p.frac01 = sx - x00
+ } else if sx-minX <= 0.5 || lowX == highX {
+ p.frac00 = y10 - sy
+ p.frac10 = sy - y00
+ } else if maxY-sy <= 0.5 {
+ p.frac10 = x11 - sx
+ p.frac11 = sx - x10
+ } else if maxX-sx <= 0.5 {
+ p.frac01 = y11 - sy
+ p.frac11 = sy - y01
+ } else {
+ p.frac00 = (x01 - sx) * (y10 - sy)
+ p.frac01 = (sx - x00) * (y11 - sy)
+ p.frac10 = (x11 - sx) * (sy - y00)
+ p.frac11 = (sx - x10) * (sy - y01)
+ }
+
+ return p
+}
+
+// TODO(crawshaw): When we have inlining, consider func (p *RGBA) Off(x, y) int
+func offRGBA(src *image.RGBA, x, y int) int {
+ return (y-src.Rect.Min.Y)*src.Stride + (x-src.Rect.Min.X)*4
+}
+func offGray(src *image.Gray, x, y int) int {
+ return (y-src.Rect.Min.Y)*src.Stride + (x - src.Rect.Min.X)
+}
diff --git a/Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/bilinear_test.go b/Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/bilinear_test.go
new file mode 100644
index 000000000..242d70546
--- /dev/null
+++ b/Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/bilinear_test.go
@@ -0,0 +1,143 @@
+// Copyright 2012 The Graphics-Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package interp
+
+import (
+ "image"
+ "image/color"
+ "testing"
+)
+
+type interpTest struct {
+ desc string
+ src []uint8
+ srcWidth int
+ x, y float64
+ expect uint8
+}
+
+func (p *interpTest) newSrc() *image.RGBA {
+ b := image.Rect(0, 0, p.srcWidth, len(p.src)/p.srcWidth)
+ src := image.NewRGBA(b)
+ i := 0
+ for y := b.Min.Y; y < b.Max.Y; y++ {
+ for x := b.Min.X; x < b.Max.X; x++ {
+ src.SetRGBA(x, y, color.RGBA{
+ R: p.src[i],
+ G: p.src[i],
+ B: p.src[i],
+ A: 0xff,
+ })
+ i++
+ }
+ }
+ return src
+}
+
+var interpTests = []interpTest{
+ {
+ desc: "center of a single white pixel should match that pixel",
+ src: []uint8{0x00},
+ srcWidth: 1,
+ x: 0.5,
+ y: 0.5,
+ expect: 0x00,
+ },
+ {
+ desc: "middle of a square is equally weighted",
+ src: []uint8{
+ 0x00, 0xff,
+ 0xff, 0x00,
+ },
+ srcWidth: 2,
+ x: 1.0,
+ y: 1.0,
+ expect: 0x80,
+ },
+ {
+ desc: "center of a pixel is just that pixel",
+ src: []uint8{
+ 0x00, 0xff,
+ 0xff, 0x00,
+ },
+ srcWidth: 2,
+ x: 1.5,
+ y: 0.5,
+ expect: 0xff,
+ },
+ {
+ desc: "asymmetry abounds",
+ src: []uint8{
+ 0xaa, 0x11, 0x55,
+ 0xff, 0x95, 0xdd,
+ },
+ srcWidth: 3,
+ x: 2.0,
+ y: 1.0,
+ expect: 0x76, // (0x11 + 0x55 + 0x95 + 0xdd) / 4
+ },
+}
+
+func TestBilinearRGBA(t *testing.T) {
+ for _, p := range interpTests {
+ src := p.newSrc()
+
+ // Fast path.
+ c := Bilinear.(RGBA).RGBA(src, p.x, p.y)
+ if c.R != c.G || c.R != c.B || c.A != 0xff {
+ t.Errorf("expect channels to match, got %v", c)
+ continue
+ }
+ if c.R != p.expect {
+ t.Errorf("%s: got 0x%02x want 0x%02x", p.desc, c.R, p.expect)
+ continue
+ }
+
+ // Standard Interp should use the fast path.
+ cStd := Bilinear.Interp(src, p.x, p.y)
+ if cStd != c {
+ t.Errorf("%s: standard mismatch got %v want %v", p.desc, cStd, c)
+ continue
+ }
+
+ // General case should match the fast path.
+ cGen := color.RGBAModel.Convert(bilinearGeneral(src, p.x, p.y))
+ r0, g0, b0, a0 := c.RGBA()
+ r1, g1, b1, a1 := cGen.RGBA()
+ if r0 != r1 || g0 != g1 || b0 != b1 || a0 != a1 {
+ t.Errorf("%s: general case mismatch got %v want %v", p.desc, c, cGen)
+ continue
+ }
+ }
+}
+
+func TestBilinearSubImage(t *testing.T) {
+ b0 := image.Rect(0, 0, 4, 4)
+ src0 := image.NewRGBA(b0)
+ b1 := image.Rect(1, 1, 3, 3)
+ src1 := src0.SubImage(b1).(*image.RGBA)
+ src1.Set(1, 1, color.RGBA{0x11, 0, 0, 0xff})
+ src1.Set(2, 1, color.RGBA{0x22, 0, 0, 0xff})
+ src1.Set(1, 2, color.RGBA{0x33, 0, 0, 0xff})
+ src1.Set(2, 2, color.RGBA{0x44, 0, 0, 0xff})
+
+ tests := []struct {
+ x, y float64
+ want uint8
+ }{
+ {1, 1, 0x11},
+ {3, 1, 0x22},
+ {1, 3, 0x33},
+ {3, 3, 0x44},
+ {2, 2, 0x2b},
+ }
+
+ for _, p := range tests {
+ c := Bilinear.(RGBA).RGBA(src1, p.x, p.y)
+ if c.R != p.want {
+ t.Errorf("(%.0f, %.0f): got 0x%02x want 0x%02x", p.x, p.y, c.R, p.want)
+ }
+ }
+}
diff --git a/Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/doc.go b/Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/doc.go
new file mode 100644
index 000000000..b115534cc
--- /dev/null
+++ b/Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/doc.go
@@ -0,0 +1,25 @@
+// Copyright 2012 The Graphics-Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package interp implements image interpolation.
+
+An interpolator provides the Interp interface, which can be used
+to interpolate a pixel:
+
+ c := interp.Bilinear.Interp(src, 1.2, 1.8)
+
+To interpolate a large number of RGBA or Gray pixels, an implementation
+may provide a fast-path by implementing the RGBA or Gray interfaces.
+
+ i1, ok := i.(interp.RGBA)
+ if ok {
+ c := i1.RGBA(src, 1.2, 1.8)
+ // use c.R, c.G, etc
+ return
+ }
+ c := i.Interp(src, 1.2, 1.8)
+ // use generic color.Color
+*/
+package interp
diff --git a/Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/interp.go b/Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/interp.go
new file mode 100644
index 000000000..560637d4a
--- /dev/null
+++ b/Godeps/_workspace/src/code.google.com/p/graphics-go/graphics/interp/interp.go
@@ -0,0 +1,29 @@
+// Copyright 2012 The Graphics-Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package interp
+
+import (
+ "image"
+ "image/color"
+)
+
+// Interp interpolates an image's color at fractional co-ordinates.
+type Interp interface {
+ // Interp interpolates (x, y).
+ Interp(src image.Image, x, y float64) color.Color
+}
+
+// RGBA is a fast-path interpolation implementation for image.RGBA.
+// It is common for an Interp to also implement RGBA.
+type RGBA interface {
+ // RGBA interpolates (x, y).
+ RGBA(src *image.RGBA, x, y float64) color.RGBA
+}
+
+// Gray is a fast-path interpolation implementation for image.Gray.
+type Gray interface {
+ // Gray interpolates (x, y).
+ Gray(src *image.Gray, x, y float64) color.Gray
+}