diff options
author | Christopher Speller <crspeller@gmail.com> | 2016-05-12 15:08:58 -0400 |
---|---|---|
committer | Christopher Speller <crspeller@gmail.com> | 2016-05-12 16:37:29 -0400 |
commit | 84d2482ddbff9564c9ad75b2d30af66e3ddfd44d (patch) | |
tree | 8bfa567d2b6381f4a996ada2deff8a16aa85a3ac /Godeps/_workspace/src/github.com/disintegration | |
parent | d1efb66ad7b017f0fbfe6f0c20843b30f396e504 (diff) | |
download | chat-84d2482ddbff9564c9ad75b2d30af66e3ddfd44d.tar.gz chat-84d2482ddbff9564c9ad75b2d30af66e3ddfd44d.tar.bz2 chat-84d2482ddbff9564c9ad75b2d30af66e3ddfd44d.zip |
Updating go depencancies. Switching to go1.6 vendoring (#2949)
Diffstat (limited to 'Godeps/_workspace/src/github.com/disintegration')
9 files changed, 0 insertions, 2045 deletions
diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/LICENSE b/Godeps/_workspace/src/github.com/disintegration/imaging/LICENSE deleted file mode 100644 index 95ae410c3..000000000 --- a/Godeps/_workspace/src/github.com/disintegration/imaging/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2012-2014 Grigory Dryapak - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE.
\ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/README.md b/Godeps/_workspace/src/github.com/disintegration/imaging/README.md deleted file mode 100644 index 25d836cef..000000000 --- a/Godeps/_workspace/src/github.com/disintegration/imaging/README.md +++ /dev/null @@ -1,194 +0,0 @@ -# Imaging
-
-Package imaging provides basic image manipulation functions (resize, rotate, flip, crop, etc.).
-This package is based on the standard Go image package and works best along with it.
-
-Image manipulation functions provided by the package take any image type
-that implements `image.Image` interface as an input, and return a new image of
-`*image.NRGBA` type (32bit RGBA colors, not premultiplied by alpha).
-
-## Installation
-
-Imaging requires Go version 1.2 or greater.
-
- go get -u github.com/disintegration/imaging
-
-## Documentation
-
-http://godoc.org/github.com/disintegration/imaging
-
-## Usage examples
-
-A few usage examples can be found below. See the documentation for the full list of supported functions.
-
-### Image resizing
-```go
-// resize srcImage to size = 128x128px using the Lanczos filter
-dstImage128 := imaging.Resize(srcImage, 128, 128, imaging.Lanczos)
-
-// resize srcImage to width = 800px preserving the aspect ratio
-dstImage800 := imaging.Resize(srcImage, 800, 0, imaging.Lanczos)
-
-// scale down srcImage to fit the 800x600px bounding box
-dstImageFit := imaging.Fit(srcImage, 800, 600, imaging.Lanczos)
-
-// resize and crop the srcImage to fill the 100x100px area
-dstImageFill := imaging.Fill(srcImage, 100, 100, imaging.Center, imaging.Lanczos)
-```
-
-Imaging supports image resizing using various resampling filters. The most notable ones:
-- `NearestNeighbor` - Fastest resampling filter, no antialiasing.
-- `Box` - Simple and fast averaging filter appropriate for downscaling. When upscaling it's similar to NearestNeighbor.
-- `Linear` - Bilinear filter, smooth and reasonably fast.
-- `MitchellNetravali` - А smooth bicubic filter.
-- `CatmullRom` - A sharp bicubic filter.
-- `Gaussian` - Blurring filter that uses gaussian function, useful for noise removal.
-- `Lanczos` - High-quality resampling filter for photographic images yielding sharp results, but it's slower than cubic filters.
-
-The full list of supported filters: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali, CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine. Custom filters can be created using ResampleFilter struct.
-
-**Resampling filters comparison**
-
-Original image. Will be resized from 512x512px to 128x128px.
-
-![srcImage](http://disintegration.github.io/imaging/in_lena_bw_512.png)
-
-Filter | Resize result
----|---
-`imaging.NearestNeighbor` | ![dstImage](http://disintegration.github.io/imaging/out_resize_down_nearest.png)
-`imaging.Box` | ![dstImage](http://disintegration.github.io/imaging/out_resize_down_box.png)
-`imaging.Linear` | ![dstImage](http://disintegration.github.io/imaging/out_resize_down_linear.png)
-`imaging.MitchellNetravali` | ![dstImage](http://disintegration.github.io/imaging/out_resize_down_mitchell.png)
-`imaging.CatmullRom` | ![dstImage](http://disintegration.github.io/imaging/out_resize_down_catrom.png)
-`imaging.Gaussian` | ![dstImage](http://disintegration.github.io/imaging/out_resize_down_gaussian.png)
-`imaging.Lanczos` | ![dstImage](http://disintegration.github.io/imaging/out_resize_down_lanczos.png)
-
-**Resize functions comparison**
-
-Original image:
-
-![srcImage](http://disintegration.github.io/imaging/in.jpg)
-
-Resize the image to width=100px and height=100px:
-
-```go
-dstImage := imaging.Resize(srcImage, 100, 100, imaging.Lanczos)
-```
-![dstImage](http://disintegration.github.io/imaging/out-comp-resize.jpg)
-
-Resize the image to width=100px preserving the aspect ratio:
-
-```go
-dstImage := imaging.Resize(srcImage, 100, 0, imaging.Lanczos)
-```
-![dstImage](http://disintegration.github.io/imaging/out-comp-fit.jpg)
-
-Resize the image to fit the 100x100px boundng box preserving the aspect ratio:
-
-```go
-dstImage := imaging.Fit(srcImage, 100, 100, imaging.Lanczos)
-```
-![dstImage](http://disintegration.github.io/imaging/out-comp-fit.jpg)
-
-Resize and crop the image with a center anchor point to fill the 100x100px area:
-
-```go
-dstImage := imaging.Fill(srcImage, 100, 100, imaging.Center, imaging.Lanczos)
-```
-![dstImage](http://disintegration.github.io/imaging/out-comp-fill.jpg)
-
-### Gaussian Blur
-```go
-dstImage := imaging.Blur(srcImage, 0.5)
-```
-
-Sigma parameter allows to control the strength of the blurring effect.
-
-Original image | Sigma = 0.5 | Sigma = 1.5
----|---|---
-![srcImage](http://disintegration.github.io/imaging/in_lena_bw_128.png) | ![dstImage](http://disintegration.github.io/imaging/out_blur_0.5.png) | ![dstImage](http://disintegration.github.io/imaging/out_blur_1.5.png)
-
-### Sharpening
-```go
-dstImage := imaging.Sharpen(srcImage, 0.5)
-```
-
-Uses gaussian function internally. Sigma parameter allows to control the strength of the sharpening effect.
-
-Original image | Sigma = 0.5 | Sigma = 1.5
----|---|---
-![srcImage](http://disintegration.github.io/imaging/in_lena_bw_128.png) | ![dstImage](http://disintegration.github.io/imaging/out_sharpen_0.5.png) | ![dstImage](http://disintegration.github.io/imaging/out_sharpen_1.5.png)
-
-### Gamma correction
-```go
-dstImage := imaging.AdjustGamma(srcImage, 0.75)
-```
-
-Original image | Gamma = 0.75 | Gamma = 1.25
----|---|---
-![srcImage](http://disintegration.github.io/imaging/in_lena_bw_128.png) | ![dstImage](http://disintegration.github.io/imaging/out_gamma_0.75.png) | ![dstImage](http://disintegration.github.io/imaging/out_gamma_1.25.png)
-
-### Contrast adjustment
-```go
-dstImage := imaging.AdjustContrast(srcImage, 20)
-```
-
-Original image | Contrast = 20 | Contrast = -20
----|---|---
-![srcImage](http://disintegration.github.io/imaging/in_lena_bw_128.png) | ![dstImage](http://disintegration.github.io/imaging/out_contrast_p20.png) | ![dstImage](http://disintegration.github.io/imaging/out_contrast_m20.png)
-
-### Brightness adjustment
-```go
-dstImage := imaging.AdjustBrightness(srcImage, 20)
-```
-
-Original image | Brightness = 20 | Brightness = -20
----|---|---
-![srcImage](http://disintegration.github.io/imaging/in_lena_bw_128.png) | ![dstImage](http://disintegration.github.io/imaging/out_brightness_p20.png) | ![dstImage](http://disintegration.github.io/imaging/out_brightness_m20.png)
-
-
-### Complete code example
-Here is the code example that loads several images, makes thumbnails of them
-and combines them together side-by-side.
-
-```go
-package main
-
-import (
- "image"
- "image/color"
-
- "github.com/disintegration/imaging"
-)
-
-func main() {
-
- // input files
- files := []string{"01.jpg", "02.jpg", "03.jpg"}
-
- // load images and make 100x100 thumbnails of them
- var thumbnails []image.Image
- for _, file := range files {
- img, err := imaging.Open(file)
- if err != nil {
- panic(err)
- }
- thumb := imaging.Thumbnail(img, 100, 100, imaging.CatmullRom)
- thumbnails = append(thumbnails, thumb)
- }
-
- // create a new blank image
- dst := imaging.New(100*len(thumbnails), 100, color.NRGBA{0, 0, 0, 0})
-
- // paste thumbnails into the new image side by side
- for i, thumb := range thumbnails {
- dst = imaging.Paste(dst, thumb, image.Pt(i*100, 0))
- }
-
- // save the combined image to file
- err := imaging.Save(dst, "dst.jpg")
- if err != nil {
- panic(err)
- }
-}
-```
diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/adjust.go b/Godeps/_workspace/src/github.com/disintegration/imaging/adjust.go deleted file mode 100644 index 9b1b83a4f..000000000 --- a/Godeps/_workspace/src/github.com/disintegration/imaging/adjust.go +++ /dev/null @@ -1,200 +0,0 @@ -package imaging - -import ( - "image" - "image/color" - "math" -) - -// AdjustFunc applies the fn function to each pixel of the img image and returns the adjusted image. -// -// Example: -// -// dstImage = imaging.AdjustFunc( -// srcImage, -// func(c color.NRGBA) color.NRGBA { -// // shift the red channel by 16 -// r := int(c.R) + 16 -// if r > 255 { -// r = 255 -// } -// return color.NRGBA{uint8(r), c.G, c.B, c.A} -// } -// ) -// -func AdjustFunc(img image.Image, fn func(c color.NRGBA) color.NRGBA) *image.NRGBA { - src := toNRGBA(img) - width := src.Bounds().Max.X - height := src.Bounds().Max.Y - dst := image.NewNRGBA(image.Rect(0, 0, width, height)) - - parallel(height, func(partStart, partEnd int) { - for y := partStart; y < partEnd; y++ { - for x := 0; x < width; x++ { - i := y*src.Stride + x*4 - j := y*dst.Stride + x*4 - - r := src.Pix[i+0] - g := src.Pix[i+1] - b := src.Pix[i+2] - a := src.Pix[i+3] - - c := fn(color.NRGBA{r, g, b, a}) - - dst.Pix[j+0] = c.R - dst.Pix[j+1] = c.G - dst.Pix[j+2] = c.B - dst.Pix[j+3] = c.A - } - } - }) - - return dst -} - -// AdjustGamma performs a gamma correction on the image and returns the adjusted image. -// Gamma parameter must be positive. Gamma = 1.0 gives the original image. -// Gamma less than 1.0 darkens the image and gamma greater than 1.0 lightens it. -// -// Example: -// -// dstImage = imaging.AdjustGamma(srcImage, 0.7) -// -func AdjustGamma(img image.Image, gamma float64) *image.NRGBA { - e := 1.0 / math.Max(gamma, 0.0001) - lut := make([]uint8, 256) - - for i := 0; i < 256; i++ { - lut[i] = clamp(math.Pow(float64(i)/255.0, e) * 255.0) - } - - fn := func(c color.NRGBA) color.NRGBA { - return color.NRGBA{lut[c.R], lut[c.G], lut[c.B], c.A} - } - - return AdjustFunc(img, fn) -} - -func sigmoid(a, b, x float64) float64 { - return 1 / (1 + math.Exp(b*(a-x))) -} - -// AdjustSigmoid changes the contrast of the image using a sigmoidal function and returns the adjusted image. -// It's a non-linear contrast change useful for photo adjustments as it preserves highlight and shadow detail. -// The midpoint parameter is the midpoint of contrast that must be between 0 and 1, typically 0.5. -// The factor parameter indicates how much to increase or decrease the contrast, typically in range (-10, 10). -// If the factor parameter is positive the image contrast is increased otherwise the contrast is decreased. -// -// Examples: -// -// dstImage = imaging.AdjustSigmoid(srcImage, 0.5, 3.0) // increase the contrast -// dstImage = imaging.AdjustSigmoid(srcImage, 0.5, -3.0) // decrease the contrast -// -func AdjustSigmoid(img image.Image, midpoint, factor float64) *image.NRGBA { - if factor == 0 { - return Clone(img) - } - - lut := make([]uint8, 256) - a := math.Min(math.Max(midpoint, 0.0), 1.0) - b := math.Abs(factor) - sig0 := sigmoid(a, b, 0) - sig1 := sigmoid(a, b, 1) - e := 1.0e-6 - - if factor > 0 { - for i := 0; i < 256; i++ { - x := float64(i) / 255.0 - sigX := sigmoid(a, b, x) - f := (sigX - sig0) / (sig1 - sig0) - lut[i] = clamp(f * 255.0) - } - } else { - for i := 0; i < 256; i++ { - x := float64(i) / 255.0 - arg := math.Min(math.Max((sig1-sig0)*x+sig0, e), 1.0-e) - f := a - math.Log(1.0/arg-1.0)/b - lut[i] = clamp(f * 255.0) - } - } - - fn := func(c color.NRGBA) color.NRGBA { - return color.NRGBA{lut[c.R], lut[c.G], lut[c.B], c.A} - } - - return AdjustFunc(img, fn) -} - -// AdjustContrast changes the contrast of the image using the percentage parameter and returns the adjusted image. -// The percentage must be in range (-100, 100). The percentage = 0 gives the original image. -// The percentage = -100 gives solid grey image. -// -// Examples: -// -// dstImage = imaging.AdjustContrast(srcImage, -10) // decrease image contrast by 10% -// dstImage = imaging.AdjustContrast(srcImage, 20) // increase image contrast by 20% -// -func AdjustContrast(img image.Image, percentage float64) *image.NRGBA { - percentage = math.Min(math.Max(percentage, -100.0), 100.0) - lut := make([]uint8, 256) - - v := (100.0 + percentage) / 100.0 - for i := 0; i < 256; i++ { - if 0 <= v && v <= 1 { - lut[i] = clamp((0.5 + (float64(i)/255.0-0.5)*v) * 255.0) - } else if 1 < v && v < 2 { - lut[i] = clamp((0.5 + (float64(i)/255.0-0.5)*(1/(2.0-v))) * 255.0) - } else { - lut[i] = uint8(float64(i)/255.0+0.5) * 255 - } - } - - fn := func(c color.NRGBA) color.NRGBA { - return color.NRGBA{lut[c.R], lut[c.G], lut[c.B], c.A} - } - - return AdjustFunc(img, fn) -} - -// AdjustBrightness changes the brightness of the image using the percentage parameter and returns the adjusted image. -// The percentage must be in range (-100, 100). The percentage = 0 gives the original image. -// The percentage = -100 gives solid black image. The percentage = 100 gives solid white image. -// -// Examples: -// -// dstImage = imaging.AdjustBrightness(srcImage, -15) // decrease image brightness by 15% -// dstImage = imaging.AdjustBrightness(srcImage, 10) // increase image brightness by 10% -// -func AdjustBrightness(img image.Image, percentage float64) *image.NRGBA { - percentage = math.Min(math.Max(percentage, -100.0), 100.0) - lut := make([]uint8, 256) - - shift := 255.0 * percentage / 100.0 - for i := 0; i < 256; i++ { - lut[i] = clamp(float64(i) + shift) - } - - fn := func(c color.NRGBA) color.NRGBA { - return color.NRGBA{lut[c.R], lut[c.G], lut[c.B], c.A} - } - - return AdjustFunc(img, fn) -} - -// Grayscale produces grayscale version of the image. -func Grayscale(img image.Image) *image.NRGBA { - fn := func(c color.NRGBA) color.NRGBA { - f := 0.299*float64(c.R) + 0.587*float64(c.G) + 0.114*float64(c.B) - y := uint8(f + 0.5) - return color.NRGBA{y, y, y, c.A} - } - return AdjustFunc(img, fn) -} - -// Invert produces inverted (negated) version of the image. -func Invert(img image.Image) *image.NRGBA { - fn := func(c color.NRGBA) color.NRGBA { - return color.NRGBA{255 - c.R, 255 - c.G, 255 - c.B, c.A} - } - return AdjustFunc(img, fn) -} diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/effects.go b/Godeps/_workspace/src/github.com/disintegration/imaging/effects.go deleted file mode 100644 index fe92e10a2..000000000 --- a/Godeps/_workspace/src/github.com/disintegration/imaging/effects.go +++ /dev/null @@ -1,187 +0,0 @@ -package imaging - -import ( - "image" - "math" -) - -func gaussianBlurKernel(x, sigma float64) float64 { - return math.Exp(-(x*x)/(2*sigma*sigma)) / (sigma * math.Sqrt(2*math.Pi)) -} - -// Blur produces a blurred version of the image using a Gaussian function. -// Sigma parameter must be positive and indicates how much the image will be blurred. -// -// Usage example: -// -// dstImage := imaging.Blur(srcImage, 3.5) -// -func Blur(img image.Image, sigma float64) *image.NRGBA { - if sigma <= 0 { - // sigma parameter must be positive! - return Clone(img) - } - - src := toNRGBA(img) - radius := int(math.Ceil(sigma * 3.0)) - kernel := make([]float64, radius+1) - - for i := 0; i <= radius; i++ { - kernel[i] = gaussianBlurKernel(float64(i), sigma) - } - - var dst *image.NRGBA - dst = blurHorizontal(src, kernel) - dst = blurVertical(dst, kernel) - - return dst -} - -func blurHorizontal(src *image.NRGBA, kernel []float64) *image.NRGBA { - radius := len(kernel) - 1 - width := src.Bounds().Max.X - height := src.Bounds().Max.Y - - dst := image.NewNRGBA(image.Rect(0, 0, width, height)) - - parallel(width, func(partStart, partEnd int) { - for x := partStart; x < partEnd; x++ { - start := x - radius - if start < 0 { - start = 0 - } - - end := x + radius - if end > width-1 { - end = width - 1 - } - - weightSum := 0.0 - for ix := start; ix <= end; ix++ { - weightSum += kernel[absint(x-ix)] - } - - for y := 0; y < height; y++ { - - r, g, b, a := 0.0, 0.0, 0.0, 0.0 - for ix := start; ix <= end; ix++ { - weight := kernel[absint(x-ix)] - i := y*src.Stride + ix*4 - r += float64(src.Pix[i+0]) * weight - g += float64(src.Pix[i+1]) * weight - b += float64(src.Pix[i+2]) * weight - a += float64(src.Pix[i+3]) * weight - } - - r = math.Min(math.Max(r/weightSum, 0.0), 255.0) - g = math.Min(math.Max(g/weightSum, 0.0), 255.0) - b = math.Min(math.Max(b/weightSum, 0.0), 255.0) - a = math.Min(math.Max(a/weightSum, 0.0), 255.0) - - j := y*dst.Stride + x*4 - dst.Pix[j+0] = uint8(r + 0.5) - dst.Pix[j+1] = uint8(g + 0.5) - dst.Pix[j+2] = uint8(b + 0.5) - dst.Pix[j+3] = uint8(a + 0.5) - - } - } - }) - - return dst -} - -func blurVertical(src *image.NRGBA, kernel []float64) *image.NRGBA { - radius := len(kernel) - 1 - width := src.Bounds().Max.X - height := src.Bounds().Max.Y - - dst := image.NewNRGBA(image.Rect(0, 0, width, height)) - - parallel(height, func(partStart, partEnd int) { - for y := partStart; y < partEnd; y++ { - start := y - radius - if start < 0 { - start = 0 - } - - end := y + radius - if end > height-1 { - end = height - 1 - } - - weightSum := 0.0 - for iy := start; iy <= end; iy++ { - weightSum += kernel[absint(y-iy)] - } - - for x := 0; x < width; x++ { - - r, g, b, a := 0.0, 0.0, 0.0, 0.0 - for iy := start; iy <= end; iy++ { - weight := kernel[absint(y-iy)] - i := iy*src.Stride + x*4 - r += float64(src.Pix[i+0]) * weight - g += float64(src.Pix[i+1]) * weight - b += float64(src.Pix[i+2]) * weight - a += float64(src.Pix[i+3]) * weight - } - - r = math.Min(math.Max(r/weightSum, 0.0), 255.0) - g = math.Min(math.Max(g/weightSum, 0.0), 255.0) - b = math.Min(math.Max(b/weightSum, 0.0), 255.0) - a = math.Min(math.Max(a/weightSum, 0.0), 255.0) - - j := y*dst.Stride + x*4 - dst.Pix[j+0] = uint8(r + 0.5) - dst.Pix[j+1] = uint8(g + 0.5) - dst.Pix[j+2] = uint8(b + 0.5) - dst.Pix[j+3] = uint8(a + 0.5) - - } - } - }) - - return dst -} - -// Sharpen produces a sharpened version of the image. -// Sigma parameter must be positive and indicates how much the image will be sharpened. -// -// Usage example: -// -// dstImage := imaging.Sharpen(srcImage, 3.5) -// -func Sharpen(img image.Image, sigma float64) *image.NRGBA { - if sigma <= 0 { - // sigma parameter must be positive! - return Clone(img) - } - - src := toNRGBA(img) - blurred := Blur(img, sigma) - - width := src.Bounds().Max.X - height := src.Bounds().Max.Y - dst := image.NewNRGBA(image.Rect(0, 0, width, height)) - - parallel(height, func(partStart, partEnd int) { - for y := partStart; y < partEnd; y++ { - for x := 0; x < width; x++ { - i := y*src.Stride + x*4 - for j := 0; j < 4; j++ { - k := i + j - val := int(src.Pix[k]) + (int(src.Pix[k]) - int(blurred.Pix[k])) - if val < 0 { - val = 0 - } else if val > 255 { - val = 255 - } - dst.Pix[k] = uint8(val) - } - } - } - }) - - return dst -} diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/helpers.go b/Godeps/_workspace/src/github.com/disintegration/imaging/helpers.go deleted file mode 100644 index 79967ae44..000000000 --- a/Godeps/_workspace/src/github.com/disintegration/imaging/helpers.go +++ /dev/null @@ -1,400 +0,0 @@ -/* -Package imaging provides basic image manipulation functions (resize, rotate, flip, crop, etc.). -This package is based on the standard Go image package and works best along with it. - -Image manipulation functions provided by the package take any image type -that implements `image.Image` interface as an input, and return a new image of -`*image.NRGBA` type (32bit RGBA colors, not premultiplied by alpha). -*/ -package imaging - -import ( - "errors" - "image" - "image/color" - "image/gif" - "image/jpeg" - "image/png" - "io" - "os" - "path/filepath" - "strings" - - "golang.org/x/image/bmp" - "golang.org/x/image/tiff" -) - -type Format int - -const ( - JPEG Format = iota - PNG - GIF - TIFF - BMP -) - -func (f Format) String() string { - switch f { - case JPEG: - return "JPEG" - case PNG: - return "PNG" - case GIF: - return "GIF" - case TIFF: - return "TIFF" - case BMP: - return "BMP" - default: - return "Unsupported" - } -} - -var ( - ErrUnsupportedFormat = errors.New("imaging: unsupported image format") -) - -// Decode reads an image from r. -func Decode(r io.Reader) (image.Image, error) { - img, _, err := image.Decode(r) - if err != nil { - return nil, err - } - return toNRGBA(img), nil -} - -// Open loads an image from file -func Open(filename string) (image.Image, error) { - file, err := os.Open(filename) - if err != nil { - return nil, err - } - defer file.Close() - img, err := Decode(file) - return img, err -} - -// Encode writes the image img to w in the specified format (JPEG, PNG, GIF, TIFF or BMP). -func Encode(w io.Writer, img image.Image, format Format) error { - var err error - switch format { - case JPEG: - var rgba *image.RGBA - if nrgba, ok := img.(*image.NRGBA); ok { - if nrgba.Opaque() { - rgba = &image.RGBA{ - Pix: nrgba.Pix, - Stride: nrgba.Stride, - Rect: nrgba.Rect, - } - } - } - if rgba != nil { - err = jpeg.Encode(w, rgba, &jpeg.Options{Quality: 95}) - } else { - err = jpeg.Encode(w, img, &jpeg.Options{Quality: 95}) - } - - case PNG: - err = png.Encode(w, img) - case GIF: - err = gif.Encode(w, img, &gif.Options{NumColors: 256}) - case TIFF: - err = tiff.Encode(w, img, &tiff.Options{Compression: tiff.Deflate, Predictor: true}) - case BMP: - err = bmp.Encode(w, img) - default: - err = ErrUnsupportedFormat - } - return err -} - -// Save saves the image to file with the specified filename. -// The format is determined from the filename extension: "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported. -func Save(img image.Image, filename string) (err error) { - formats := map[string]Format{ - ".jpg": JPEG, - ".jpeg": JPEG, - ".png": PNG, - ".tif": TIFF, - ".tiff": TIFF, - ".bmp": BMP, - ".gif": GIF, - } - - ext := strings.ToLower(filepath.Ext(filename)) - f, ok := formats[ext] - if !ok { - return ErrUnsupportedFormat - } - - file, err := os.Create(filename) - if err != nil { - return err - } - defer file.Close() - - return Encode(file, img, f) -} - -// New creates a new image with the specified width and height, and fills it with the specified color. -func New(width, height int, fillColor color.Color) *image.NRGBA { - if width <= 0 || height <= 0 { - return &image.NRGBA{} - } - - dst := image.NewNRGBA(image.Rect(0, 0, width, height)) - c := color.NRGBAModel.Convert(fillColor).(color.NRGBA) - - if c.R == 0 && c.G == 0 && c.B == 0 && c.A == 0 { - return dst - } - - cs := []uint8{c.R, c.G, c.B, c.A} - - // fill the first row - for x := 0; x < width; x++ { - copy(dst.Pix[x*4:(x+1)*4], cs) - } - // copy the first row to other rows - for y := 1; y < height; y++ { - copy(dst.Pix[y*dst.Stride:y*dst.Stride+width*4], dst.Pix[0:width*4]) - } - - return dst -} - -// Clone returns a copy of the given image. -func Clone(img image.Image) *image.NRGBA { - srcBounds := img.Bounds() - srcMinX := srcBounds.Min.X - srcMinY := srcBounds.Min.Y - - dstBounds := srcBounds.Sub(srcBounds.Min) - dstW := dstBounds.Dx() - dstH := dstBounds.Dy() - dst := image.NewNRGBA(dstBounds) - - switch src := img.(type) { - - case *image.NRGBA: - rowSize := srcBounds.Dx() * 4 - parallel(dstH, func(partStart, partEnd int) { - for dstY := partStart; dstY < partEnd; dstY++ { - di := dst.PixOffset(0, dstY) - si := src.PixOffset(srcMinX, srcMinY+dstY) - copy(dst.Pix[di:di+rowSize], src.Pix[si:si+rowSize]) - } - }) - - case *image.NRGBA64: - parallel(dstH, func(partStart, partEnd int) { - for dstY := partStart; dstY < partEnd; dstY++ { - di := dst.PixOffset(0, dstY) - si := src.PixOffset(srcMinX, srcMinY+dstY) - for dstX := 0; dstX < dstW; dstX++ { - - dst.Pix[di+0] = src.Pix[si+0] - dst.Pix[di+1] = src.Pix[si+2] - dst.Pix[di+2] = src.Pix[si+4] - dst.Pix[di+3] = src.Pix[si+6] - - di += 4 - si += 8 - - } - } - }) - - case *image.RGBA: - parallel(dstH, func(partStart, partEnd int) { - for dstY := partStart; dstY < partEnd; dstY++ { - di := dst.PixOffset(0, dstY) - si := src.PixOffset(srcMinX, srcMinY+dstY) - for dstX := 0; dstX < dstW; dstX++ { - - a := src.Pix[si+3] - dst.Pix[di+3] = a - switch a { - case 0: - dst.Pix[di+0] = 0 - dst.Pix[di+1] = 0 - dst.Pix[di+2] = 0 - case 0xff: - dst.Pix[di+0] = src.Pix[si+0] - dst.Pix[di+1] = src.Pix[si+1] - dst.Pix[di+2] = src.Pix[si+2] - default: - var tmp uint16 - tmp = uint16(src.Pix[si+0]) * 0xff / uint16(a) - dst.Pix[di+0] = uint8(tmp) - tmp = uint16(src.Pix[si+1]) * 0xff / uint16(a) - dst.Pix[di+1] = uint8(tmp) - tmp = uint16(src.Pix[si+2]) * 0xff / uint16(a) - dst.Pix[di+2] = uint8(tmp) - } - - di += 4 - si += 4 - - } - } - }) - - case *image.RGBA64: - parallel(dstH, func(partStart, partEnd int) { - for dstY := partStart; dstY < partEnd; dstY++ { - di := dst.PixOffset(0, dstY) - si := src.PixOffset(srcMinX, srcMinY+dstY) - for dstX := 0; dstX < dstW; dstX++ { - - a := src.Pix[si+6] - dst.Pix[di+3] = a - switch a { - case 0: - dst.Pix[di+0] = 0 - dst.Pix[di+1] = 0 - dst.Pix[di+2] = 0 - case 0xff: - dst.Pix[di+0] = src.Pix[si+0] - dst.Pix[di+1] = src.Pix[si+2] - dst.Pix[di+2] = src.Pix[si+4] - default: - var tmp uint16 - tmp = uint16(src.Pix[si+0]) * 0xff / uint16(a) - dst.Pix[di+0] = uint8(tmp) - tmp = uint16(src.Pix[si+2]) * 0xff / uint16(a) - dst.Pix[di+1] = uint8(tmp) - tmp = uint16(src.Pix[si+4]) * 0xff / uint16(a) - dst.Pix[di+2] = uint8(tmp) - } - - di += 4 - si += 8 - - } - } - }) - - case *image.Gray: - parallel(dstH, func(partStart, partEnd int) { - for dstY := partStart; dstY < partEnd; dstY++ { - di := dst.PixOffset(0, dstY) - si := src.PixOffset(srcMinX, srcMinY+dstY) - for dstX := 0; dstX < dstW; dstX++ { - - c := src.Pix[si] - dst.Pix[di+0] = c - dst.Pix[di+1] = c - dst.Pix[di+2] = c - dst.Pix[di+3] = 0xff - - di += 4 - si += 1 - - } - } - }) - - case *image.Gray16: - parallel(dstH, func(partStart, partEnd int) { - for dstY := partStart; dstY < partEnd; dstY++ { - di := dst.PixOffset(0, dstY) - si := src.PixOffset(srcMinX, srcMinY+dstY) - for dstX := 0; dstX < dstW; dstX++ { - - c := src.Pix[si] - dst.Pix[di+0] = c - dst.Pix[di+1] = c - dst.Pix[di+2] = c - dst.Pix[di+3] = 0xff - - di += 4 - si += 2 - - } - } - }) - - case *image.YCbCr: - parallel(dstH, func(partStart, partEnd int) { - for dstY := partStart; dstY < partEnd; dstY++ { - di := dst.PixOffset(0, dstY) - for dstX := 0; dstX < dstW; dstX++ { - - srcX := srcMinX + dstX - srcY := srcMinY + dstY - siy := src.YOffset(srcX, srcY) - sic := src.COffset(srcX, srcY) - r, g, b := color.YCbCrToRGB(src.Y[siy], src.Cb[sic], src.Cr[sic]) - dst.Pix[di+0] = r - dst.Pix[di+1] = g - dst.Pix[di+2] = b - dst.Pix[di+3] = 0xff - - di += 4 - - } - } - }) - - case *image.Paletted: - plen := len(src.Palette) - pnew := make([]color.NRGBA, plen) - for i := 0; i < plen; i++ { - pnew[i] = color.NRGBAModel.Convert(src.Palette[i]).(color.NRGBA) - } - - parallel(dstH, func(partStart, partEnd int) { - for dstY := partStart; dstY < partEnd; dstY++ { - di := dst.PixOffset(0, dstY) - si := src.PixOffset(srcMinX, srcMinY+dstY) - for dstX := 0; dstX < dstW; dstX++ { - - c := pnew[src.Pix[si]] - dst.Pix[di+0] = c.R - dst.Pix[di+1] = c.G - dst.Pix[di+2] = c.B - dst.Pix[di+3] = c.A - - di += 4 - si += 1 - - } - } - }) - - default: - parallel(dstH, func(partStart, partEnd int) { - for dstY := partStart; dstY < partEnd; dstY++ { - di := dst.PixOffset(0, dstY) - for dstX := 0; dstX < dstW; dstX++ { - - c := color.NRGBAModel.Convert(img.At(srcMinX+dstX, srcMinY+dstY)).(color.NRGBA) - dst.Pix[di+0] = c.R - dst.Pix[di+1] = c.G - dst.Pix[di+2] = c.B - dst.Pix[di+3] = c.A - - di += 4 - - } - } - }) - - } - - return dst -} - -// This function used internally to convert any image type to NRGBA if needed. -func toNRGBA(img image.Image) *image.NRGBA { - srcBounds := img.Bounds() - if srcBounds.Min.X == 0 && srcBounds.Min.Y == 0 { - if src0, ok := img.(*image.NRGBA); ok { - return src0 - } - } - return Clone(img) -} diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/resize.go b/Godeps/_workspace/src/github.com/disintegration/imaging/resize.go deleted file mode 100644 index 3c792e904..000000000 --- a/Godeps/_workspace/src/github.com/disintegration/imaging/resize.go +++ /dev/null @@ -1,583 +0,0 @@ -package imaging - -import ( - "image" - "math" -) - -type iwpair struct { - i int - w int32 -} - -type pweights struct { - iwpairs []iwpair - wsum int32 -} - -func precomputeWeights(dstSize, srcSize int, filter ResampleFilter) []pweights { - du := float64(srcSize) / float64(dstSize) - scale := du - if scale < 1.0 { - scale = 1.0 - } - ru := math.Ceil(scale * filter.Support) - - out := make([]pweights, dstSize) - - for v := 0; v < dstSize; v++ { - fu := (float64(v)+0.5)*du - 0.5 - - startu := int(math.Ceil(fu - ru)) - if startu < 0 { - startu = 0 - } - endu := int(math.Floor(fu + ru)) - if endu > srcSize-1 { - endu = srcSize - 1 - } - - wsum := int32(0) - for u := startu; u <= endu; u++ { - w := int32(0xff * filter.Kernel((float64(u)-fu)/scale)) - if w != 0 { - wsum += w - out[v].iwpairs = append(out[v].iwpairs, iwpair{u, w}) - } - } - out[v].wsum = wsum - } - - return out -} - -// Resize resizes the image to the specified width and height using the specified resampling -// filter and returns the transformed image. If one of width or height is 0, the image aspect -// ratio is preserved. -// -// Supported resample filters: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali, -// CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine. -// -// Usage example: -// -// dstImage := imaging.Resize(srcImage, 800, 600, imaging.Lanczos) -// -func Resize(img image.Image, width, height int, filter ResampleFilter) *image.NRGBA { - dstW, dstH := width, height - - if dstW < 0 || dstH < 0 { - return &image.NRGBA{} - } - if dstW == 0 && dstH == 0 { - return &image.NRGBA{} - } - - src := toNRGBA(img) - - srcW := src.Bounds().Max.X - srcH := src.Bounds().Max.Y - - if srcW <= 0 || srcH <= 0 { - return &image.NRGBA{} - } - - // if new width or height is 0 then preserve aspect ratio, minimum 1px - if dstW == 0 { - tmpW := float64(dstH) * float64(srcW) / float64(srcH) - dstW = int(math.Max(1.0, math.Floor(tmpW+0.5))) - } - if dstH == 0 { - tmpH := float64(dstW) * float64(srcH) / float64(srcW) - dstH = int(math.Max(1.0, math.Floor(tmpH+0.5))) - } - - var dst *image.NRGBA - - if filter.Support <= 0.0 { - // nearest-neighbor special case - dst = resizeNearest(src, dstW, dstH) - - } else { - // two-pass resize - if srcW != dstW { - dst = resizeHorizontal(src, dstW, filter) - } else { - dst = src - } - - if srcH != dstH { - dst = resizeVertical(dst, dstH, filter) - } - } - - return dst -} - -func resizeHorizontal(src *image.NRGBA, width int, filter ResampleFilter) *image.NRGBA { - srcBounds := src.Bounds() - srcW := srcBounds.Max.X - srcH := srcBounds.Max.Y - - dstW := width - dstH := srcH - - dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) - - weights := precomputeWeights(dstW, srcW, filter) - - parallel(dstH, func(partStart, partEnd int) { - for dstY := partStart; dstY < partEnd; dstY++ { - for dstX := 0; dstX < dstW; dstX++ { - var c [4]int32 - for _, iw := range weights[dstX].iwpairs { - i := dstY*src.Stride + iw.i*4 - c[0] += int32(src.Pix[i+0]) * iw.w - c[1] += int32(src.Pix[i+1]) * iw.w - c[2] += int32(src.Pix[i+2]) * iw.w - c[3] += int32(src.Pix[i+3]) * iw.w - } - j := dstY*dst.Stride + dstX*4 - sum := weights[dstX].wsum - dst.Pix[j+0] = clampint32(int32(float32(c[0])/float32(sum) + 0.5)) - dst.Pix[j+1] = clampint32(int32(float32(c[1])/float32(sum) + 0.5)) - dst.Pix[j+2] = clampint32(int32(float32(c[2])/float32(sum) + 0.5)) - dst.Pix[j+3] = clampint32(int32(float32(c[3])/float32(sum) + 0.5)) - } - } - }) - - return dst -} - -func resizeVertical(src *image.NRGBA, height int, filter ResampleFilter) *image.NRGBA { - srcBounds := src.Bounds() - srcW := srcBounds.Max.X - srcH := srcBounds.Max.Y - - dstW := srcW - dstH := height - - dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) - - weights := precomputeWeights(dstH, srcH, filter) - - parallel(dstW, func(partStart, partEnd int) { - - for dstX := partStart; dstX < partEnd; dstX++ { - for dstY := 0; dstY < dstH; dstY++ { - var c [4]int32 - for _, iw := range weights[dstY].iwpairs { - i := iw.i*src.Stride + dstX*4 - c[0] += int32(src.Pix[i+0]) * iw.w - c[1] += int32(src.Pix[i+1]) * iw.w - c[2] += int32(src.Pix[i+2]) * iw.w - c[3] += int32(src.Pix[i+3]) * iw.w - } - j := dstY*dst.Stride + dstX*4 - sum := weights[dstY].wsum - dst.Pix[j+0] = clampint32(int32(float32(c[0])/float32(sum) + 0.5)) - dst.Pix[j+1] = clampint32(int32(float32(c[1])/float32(sum) + 0.5)) - dst.Pix[j+2] = clampint32(int32(float32(c[2])/float32(sum) + 0.5)) - dst.Pix[j+3] = clampint32(int32(float32(c[3])/float32(sum) + 0.5)) - } - } - - }) - - return dst -} - -// fast nearest-neighbor resize, no filtering -func resizeNearest(src *image.NRGBA, width, height int) *image.NRGBA { - dstW, dstH := width, height - - srcBounds := src.Bounds() - srcW := srcBounds.Max.X - srcH := srcBounds.Max.Y - - dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) - - dx := float64(srcW) / float64(dstW) - dy := float64(srcH) / float64(dstH) - - parallel(dstH, func(partStart, partEnd int) { - - for dstY := partStart; dstY < partEnd; dstY++ { - fy := (float64(dstY)+0.5)*dy - 0.5 - - for dstX := 0; dstX < dstW; dstX++ { - fx := (float64(dstX)+0.5)*dx - 0.5 - - srcX := int(math.Min(math.Max(math.Floor(fx+0.5), 0.0), float64(srcW))) - srcY := int(math.Min(math.Max(math.Floor(fy+0.5), 0.0), float64(srcH))) - - srcOff := srcY*src.Stride + srcX*4 - dstOff := dstY*dst.Stride + dstX*4 - - copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4]) - } - } - - }) - - return dst -} - -// Fit scales down the image using the specified resample filter to fit the specified -// maximum width and height and returns the transformed image. -// -// Supported resample filters: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali, -// CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine. -// -// Usage example: -// -// dstImage := imaging.Fit(srcImage, 800, 600, imaging.Lanczos) -// -func Fit(img image.Image, width, height int, filter ResampleFilter) *image.NRGBA { - maxW, maxH := width, height - - if maxW <= 0 || maxH <= 0 { - return &image.NRGBA{} - } - - srcBounds := img.Bounds() - srcW := srcBounds.Dx() - srcH := srcBounds.Dy() - - if srcW <= 0 || srcH <= 0 { - return &image.NRGBA{} - } - - if srcW <= maxW && srcH <= maxH { - return Clone(img) - } - - srcAspectRatio := float64(srcW) / float64(srcH) - maxAspectRatio := float64(maxW) / float64(maxH) - - var newW, newH int - if srcAspectRatio > maxAspectRatio { - newW = maxW - newH = int(float64(newW) / srcAspectRatio) - } else { - newH = maxH - newW = int(float64(newH) * srcAspectRatio) - } - - return Resize(img, newW, newH, filter) -} - -// Fill scales the image to the smallest possible size that will cover the specified dimensions, -// crops the resized image to the specified dimensions using the given anchor point and returns -// the transformed image. -// -// Supported resample filters: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali, -// CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine. -// -// Usage example: -// -// dstImage := imaging.Fill(srcImage, 800, 600, imaging.Center, imaging.Lanczos) -// -func Fill(img image.Image, width, height int, anchor Anchor, filter ResampleFilter) *image.NRGBA { - minW, minH := width, height - - if minW <= 0 || minH <= 0 { - return &image.NRGBA{} - } - - srcBounds := img.Bounds() - srcW := srcBounds.Dx() - srcH := srcBounds.Dy() - - if srcW <= 0 || srcH <= 0 { - return &image.NRGBA{} - } - - if srcW == minW && srcH == minH { - return Clone(img) - } - - srcAspectRatio := float64(srcW) / float64(srcH) - minAspectRatio := float64(minW) / float64(minH) - - var tmp *image.NRGBA - if srcAspectRatio < minAspectRatio { - tmp = Resize(img, minW, 0, filter) - } else { - tmp = Resize(img, 0, minH, filter) - } - - return CropAnchor(tmp, minW, minH, anchor) -} - -// Thumbnail scales the image up or down using the specified resample filter, crops it -// to the specified width and hight and returns the transformed image. -// -// Supported resample filters: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali, -// CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine. -// -// Usage example: -// -// dstImage := imaging.Thumbnail(srcImage, 100, 100, imaging.Lanczos) -// -func Thumbnail(img image.Image, width, height int, filter ResampleFilter) *image.NRGBA { - return Fill(img, width, height, Center, filter) -} - -// Resample filter struct. It can be used to make custom filters. -// -// Supported resample filters: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali, -// CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine. -// -// General filter recommendations: -// -// - Lanczos -// Probably the best resampling filter for photographic images yielding sharp results, -// but it's slower than cubic filters (see below). -// -// - CatmullRom -// A sharp cubic filter. It's a good filter for both upscaling and downscaling if sharp results are needed. -// -// - MitchellNetravali -// A high quality cubic filter that produces smoother results with less ringing than CatmullRom. -// -// - BSpline -// A good filter if a very smooth output is needed. -// -// - Linear -// Bilinear interpolation filter, produces reasonably good, smooth output. It's faster than cubic filters. -// -// - Box -// Simple and fast resampling filter appropriate for downscaling. -// When upscaling it's similar to NearestNeighbor. -// -// - NearestNeighbor -// Fastest resample filter, no antialiasing at all. Rarely used. -// -type ResampleFilter struct { - Support float64 - Kernel func(float64) float64 -} - -// Nearest-neighbor filter, no anti-aliasing. -var NearestNeighbor ResampleFilter - -// Box filter (averaging pixels). -var Box ResampleFilter - -// Linear filter. -var Linear ResampleFilter - -// Hermite cubic spline filter (BC-spline; B=0; C=0). -var Hermite ResampleFilter - -// Mitchell-Netravali cubic filter (BC-spline; B=1/3; C=1/3). -var MitchellNetravali ResampleFilter - -// Catmull-Rom - sharp cubic filter (BC-spline; B=0; C=0.5). -var CatmullRom ResampleFilter - -// Cubic B-spline - smooth cubic filter (BC-spline; B=1; C=0). -var BSpline ResampleFilter - -// Gaussian Blurring Filter. -var Gaussian ResampleFilter - -// Bartlett-windowed sinc filter (3 lobes). -var Bartlett ResampleFilter - -// Lanczos filter (3 lobes). -var Lanczos ResampleFilter - -// Hann-windowed sinc filter (3 lobes). -var Hann ResampleFilter - -// Hamming-windowed sinc filter (3 lobes). -var Hamming ResampleFilter - -// Blackman-windowed sinc filter (3 lobes). -var Blackman ResampleFilter - -// Welch-windowed sinc filter (parabolic window, 3 lobes). -var Welch ResampleFilter - -// Cosine-windowed sinc filter (3 lobes). -var Cosine ResampleFilter - -func bcspline(x, b, c float64) float64 { - x = math.Abs(x) - if x < 1.0 { - return ((12-9*b-6*c)*x*x*x + (-18+12*b+6*c)*x*x + (6 - 2*b)) / 6 - } - if x < 2.0 { - return ((-b-6*c)*x*x*x + (6*b+30*c)*x*x + (-12*b-48*c)*x + (8*b + 24*c)) / 6 - } - return 0 -} - -func sinc(x float64) float64 { - if x == 0 { - return 1 - } - return math.Sin(math.Pi*x) / (math.Pi * x) -} - -func init() { - NearestNeighbor = ResampleFilter{ - Support: 0.0, // special case - not applying the filter - } - - Box = ResampleFilter{ - Support: 0.5, - Kernel: func(x float64) float64 { - x = math.Abs(x) - if x <= 0.5 { - return 1.0 - } - return 0 - }, - } - - Linear = ResampleFilter{ - Support: 1.0, - Kernel: func(x float64) float64 { - x = math.Abs(x) - if x < 1.0 { - return 1.0 - x - } - return 0 - }, - } - - Hermite = ResampleFilter{ - Support: 1.0, - Kernel: func(x float64) float64 { - x = math.Abs(x) - if x < 1.0 { - return bcspline(x, 0.0, 0.0) - } - return 0 - }, - } - - MitchellNetravali = ResampleFilter{ - Support: 2.0, - Kernel: func(x float64) float64 { - x = math.Abs(x) - if x < 2.0 { - return bcspline(x, 1.0/3.0, 1.0/3.0) - } - return 0 - }, - } - - CatmullRom = ResampleFilter{ - Support: 2.0, - Kernel: func(x float64) float64 { - x = math.Abs(x) - if x < 2.0 { - return bcspline(x, 0.0, 0.5) - } - return 0 - }, - } - - BSpline = ResampleFilter{ - Support: 2.0, - Kernel: func(x float64) float64 { - x = math.Abs(x) - if x < 2.0 { - return bcspline(x, 1.0, 0.0) - } - return 0 - }, - } - - Gaussian = ResampleFilter{ - Support: 2.0, - Kernel: func(x float64) float64 { - x = math.Abs(x) - if x < 2.0 { - return math.Exp(-2 * x * x) - } - return 0 - }, - } - - Bartlett = ResampleFilter{ - Support: 3.0, - Kernel: func(x float64) float64 { - x = math.Abs(x) - if x < 3.0 { - return sinc(x) * (3.0 - x) / 3.0 - } - return 0 - }, - } - - Lanczos = ResampleFilter{ - Support: 3.0, - Kernel: func(x float64) float64 { - x = math.Abs(x) - if x < 3.0 { - return sinc(x) * sinc(x/3.0) - } - return 0 - }, - } - - Hann = ResampleFilter{ - Support: 3.0, - Kernel: func(x float64) float64 { - x = math.Abs(x) - if x < 3.0 { - return sinc(x) * (0.5 + 0.5*math.Cos(math.Pi*x/3.0)) - } - return 0 - }, - } - - Hamming = ResampleFilter{ - Support: 3.0, - Kernel: func(x float64) float64 { - x = math.Abs(x) - if x < 3.0 { - return sinc(x) * (0.54 + 0.46*math.Cos(math.Pi*x/3.0)) - } - return 0 - }, - } - - Blackman = ResampleFilter{ - Support: 3.0, - Kernel: func(x float64) float64 { - x = math.Abs(x) - if x < 3.0 { - return sinc(x) * (0.42 - 0.5*math.Cos(math.Pi*x/3.0+math.Pi) + 0.08*math.Cos(2.0*math.Pi*x/3.0)) - } - return 0 - }, - } - - Welch = ResampleFilter{ - Support: 3.0, - Kernel: func(x float64) float64 { - x = math.Abs(x) - if x < 3.0 { - return sinc(x) * (1.0 - (x * x / 9.0)) - } - return 0 - }, - } - - Cosine = ResampleFilter{ - Support: 3.0, - Kernel: func(x float64) float64 { - x = math.Abs(x) - if x < 3.0 { - return sinc(x) * math.Cos((math.Pi/2.0)*(x/3.0)) - } - return 0 - }, - } -} diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/tools.go b/Godeps/_workspace/src/github.com/disintegration/imaging/tools.go deleted file mode 100644 index 2c39c900a..000000000 --- a/Godeps/_workspace/src/github.com/disintegration/imaging/tools.go +++ /dev/null @@ -1,182 +0,0 @@ -package imaging - -import ( - "image" - "math" -) - -// Anchor is the anchor point for image alignment. -type Anchor int - -const ( - Center Anchor = iota - TopLeft - Top - TopRight - Left - Right - BottomLeft - Bottom - BottomRight -) - -func anchorPt(b image.Rectangle, w, h int, anchor Anchor) image.Point { - var x, y int - switch anchor { - case TopLeft: - x = b.Min.X - y = b.Min.Y - case Top: - x = b.Min.X + (b.Dx()-w)/2 - y = b.Min.Y - case TopRight: - x = b.Max.X - w - y = b.Min.Y - case Left: - x = b.Min.X - y = b.Min.Y + (b.Dy()-h)/2 - case Right: - x = b.Max.X - w - y = b.Min.Y + (b.Dy()-h)/2 - case BottomLeft: - x = b.Min.X - y = b.Max.Y - h - case Bottom: - x = b.Min.X + (b.Dx()-w)/2 - y = b.Max.Y - h - case BottomRight: - x = b.Max.X - w - y = b.Max.Y - h - default: - x = b.Min.X + (b.Dx()-w)/2 - y = b.Min.Y + (b.Dy()-h)/2 - } - return image.Pt(x, y) -} - -// Crop cuts out a rectangular region with the specified bounds -// from the image and returns the cropped image. -func Crop(img image.Image, rect image.Rectangle) *image.NRGBA { - src := toNRGBA(img) - srcRect := rect.Sub(img.Bounds().Min) - sub := src.SubImage(srcRect) - return Clone(sub) // New image Bounds().Min point will be (0, 0) -} - -// CropAnchor cuts out a rectangular region with the specified size -// from the image using the specified anchor point and returns the cropped image. -func CropAnchor(img image.Image, width, height int, anchor Anchor) *image.NRGBA { - srcBounds := img.Bounds() - pt := anchorPt(srcBounds, width, height, anchor) - r := image.Rect(0, 0, width, height).Add(pt) - b := srcBounds.Intersect(r) - return Crop(img, b) -} - -// CropCenter cuts out a rectangular region with the specified size -// from the center of the image and returns the cropped image. -func CropCenter(img image.Image, width, height int) *image.NRGBA { - return CropAnchor(img, width, height, Center) -} - -// Paste pastes the img image to the background image at the specified position and returns the combined image. -func Paste(background, img image.Image, pos image.Point) *image.NRGBA { - src := toNRGBA(img) - dst := Clone(background) // cloned image bounds start at (0, 0) - startPt := pos.Sub(background.Bounds().Min) // so we should translate start point - endPt := startPt.Add(src.Bounds().Size()) - pasteBounds := image.Rectangle{startPt, endPt} - - if dst.Bounds().Overlaps(pasteBounds) { - intersectBounds := dst.Bounds().Intersect(pasteBounds) - - rowSize := intersectBounds.Dx() * 4 - numRows := intersectBounds.Dy() - - srcStartX := intersectBounds.Min.X - pasteBounds.Min.X - srcStartY := intersectBounds.Min.Y - pasteBounds.Min.Y - - i0 := dst.PixOffset(intersectBounds.Min.X, intersectBounds.Min.Y) - j0 := src.PixOffset(srcStartX, srcStartY) - - di := dst.Stride - dj := src.Stride - - for row := 0; row < numRows; row++ { - copy(dst.Pix[i0:i0+rowSize], src.Pix[j0:j0+rowSize]) - i0 += di - j0 += dj - } - } - - return dst -} - -// PasteCenter pastes the img image to the center of the background image and returns the combined image. -func PasteCenter(background, img image.Image) *image.NRGBA { - bgBounds := background.Bounds() - bgW := bgBounds.Dx() - bgH := bgBounds.Dy() - bgMinX := bgBounds.Min.X - bgMinY := bgBounds.Min.Y - - centerX := bgMinX + bgW/2 - centerY := bgMinY + bgH/2 - - x0 := centerX - img.Bounds().Dx()/2 - y0 := centerY - img.Bounds().Dy()/2 - - return Paste(background, img, image.Pt(x0, y0)) -} - -// Overlay draws the img image over the background image at given position -// and returns the combined image. Opacity parameter is the opacity of the img -// image layer, used to compose the images, it must be from 0.0 to 1.0. -// -// Usage examples: -// -// // draw the sprite over the background at position (50, 50) -// dstImage := imaging.Overlay(backgroundImage, spriteImage, image.Pt(50, 50), 1.0) -// -// // blend two opaque images of the same size -// dstImage := imaging.Overlay(imageOne, imageTwo, image.Pt(0, 0), 0.5) -// -func Overlay(background, img image.Image, pos image.Point, opacity float64) *image.NRGBA { - opacity = math.Min(math.Max(opacity, 0.0), 1.0) // check: 0.0 <= opacity <= 1.0 - - src := toNRGBA(img) - dst := Clone(background) // cloned image bounds start at (0, 0) - startPt := pos.Sub(background.Bounds().Min) // so we should translate start point - endPt := startPt.Add(src.Bounds().Size()) - pasteBounds := image.Rectangle{startPt, endPt} - - if dst.Bounds().Overlaps(pasteBounds) { - intersectBounds := dst.Bounds().Intersect(pasteBounds) - - for y := intersectBounds.Min.Y; y < intersectBounds.Max.Y; y++ { - for x := intersectBounds.Min.X; x < intersectBounds.Max.X; x++ { - i := y*dst.Stride + x*4 - - srcX := x - pasteBounds.Min.X - srcY := y - pasteBounds.Min.Y - j := srcY*src.Stride + srcX*4 - - a1 := float64(dst.Pix[i+3]) - a2 := float64(src.Pix[j+3]) - - coef2 := opacity * a2 / 255.0 - coef1 := (1 - coef2) * a1 / 255.0 - coefSum := coef1 + coef2 - coef1 /= coefSum - coef2 /= coefSum - - dst.Pix[i+0] = uint8(float64(dst.Pix[i+0])*coef1 + float64(src.Pix[j+0])*coef2) - dst.Pix[i+1] = uint8(float64(dst.Pix[i+1])*coef1 + float64(src.Pix[j+1])*coef2) - dst.Pix[i+2] = uint8(float64(dst.Pix[i+2])*coef1 + float64(src.Pix[j+2])*coef2) - dst.Pix[i+3] = uint8(math.Min(a1+a2*opacity*(255.0-a1)/255.0, 255.0)) - } - } - } - - return dst -} diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/transform.go b/Godeps/_workspace/src/github.com/disintegration/imaging/transform.go deleted file mode 100644 index a11601bba..000000000 --- a/Godeps/_workspace/src/github.com/disintegration/imaging/transform.go +++ /dev/null @@ -1,201 +0,0 @@ -package imaging - -import ( - "image" -) - -// Rotate90 rotates the image 90 degrees counterclockwise and returns the transformed image. -func Rotate90(img image.Image) *image.NRGBA { - src := toNRGBA(img) - srcW := src.Bounds().Max.X - srcH := src.Bounds().Max.Y - dstW := srcH - dstH := srcW - dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) - - parallel(dstH, func(partStart, partEnd int) { - - for dstY := partStart; dstY < partEnd; dstY++ { - for dstX := 0; dstX < dstW; dstX++ { - srcX := dstH - dstY - 1 - srcY := dstX - - srcOff := srcY*src.Stride + srcX*4 - dstOff := dstY*dst.Stride + dstX*4 - - copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4]) - } - } - - }) - - return dst -} - -// Rotate180 rotates the image 180 degrees counterclockwise and returns the transformed image. -func Rotate180(img image.Image) *image.NRGBA { - src := toNRGBA(img) - srcW := src.Bounds().Max.X - srcH := src.Bounds().Max.Y - dstW := srcW - dstH := srcH - dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) - - parallel(dstH, func(partStart, partEnd int) { - - for dstY := partStart; dstY < partEnd; dstY++ { - for dstX := 0; dstX < dstW; dstX++ { - srcX := dstW - dstX - 1 - srcY := dstH - dstY - 1 - - srcOff := srcY*src.Stride + srcX*4 - dstOff := dstY*dst.Stride + dstX*4 - - copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4]) - } - } - - }) - - return dst -} - -// Rotate270 rotates the image 270 degrees counterclockwise and returns the transformed image. -func Rotate270(img image.Image) *image.NRGBA { - src := toNRGBA(img) - srcW := src.Bounds().Max.X - srcH := src.Bounds().Max.Y - dstW := srcH - dstH := srcW - dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) - - parallel(dstH, func(partStart, partEnd int) { - - for dstY := partStart; dstY < partEnd; dstY++ { - for dstX := 0; dstX < dstW; dstX++ { - srcX := dstY - srcY := dstW - dstX - 1 - - srcOff := srcY*src.Stride + srcX*4 - dstOff := dstY*dst.Stride + dstX*4 - - copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4]) - } - } - - }) - - return dst -} - -// FlipH flips the image horizontally (from left to right) and returns the transformed image. -func FlipH(img image.Image) *image.NRGBA { - src := toNRGBA(img) - srcW := src.Bounds().Max.X - srcH := src.Bounds().Max.Y - dstW := srcW - dstH := srcH - dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) - - parallel(dstH, func(partStart, partEnd int) { - - for dstY := partStart; dstY < partEnd; dstY++ { - for dstX := 0; dstX < dstW; dstX++ { - srcX := dstW - dstX - 1 - srcY := dstY - - srcOff := srcY*src.Stride + srcX*4 - dstOff := dstY*dst.Stride + dstX*4 - - copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4]) - } - } - - }) - - return dst -} - -// FlipV flips the image vertically (from top to bottom) and returns the transformed image. -func FlipV(img image.Image) *image.NRGBA { - src := toNRGBA(img) - srcW := src.Bounds().Max.X - srcH := src.Bounds().Max.Y - dstW := srcW - dstH := srcH - dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) - - parallel(dstH, func(partStart, partEnd int) { - - for dstY := partStart; dstY < partEnd; dstY++ { - for dstX := 0; dstX < dstW; dstX++ { - srcX := dstX - srcY := dstH - dstY - 1 - - srcOff := srcY*src.Stride + srcX*4 - dstOff := dstY*dst.Stride + dstX*4 - - copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4]) - } - } - - }) - - return dst -} - -// Transpose flips the image horizontally and rotates 90 degrees counter-clockwise. -func Transpose(img image.Image) *image.NRGBA { - src := toNRGBA(img) - srcW := src.Bounds().Max.X - srcH := src.Bounds().Max.Y - dstW := srcH - dstH := srcW - dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) - - parallel(dstH, func(partStart, partEnd int) { - - for dstY := partStart; dstY < partEnd; dstY++ { - for dstX := 0; dstX < dstW; dstX++ { - srcX := dstY - srcY := dstX - - srcOff := srcY*src.Stride + srcX*4 - dstOff := dstY*dst.Stride + dstX*4 - - copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4]) - } - } - - }) - - return dst -} - -// Transverse flips the image vertically and rotates 90 degrees counter-clockwise. -func Transverse(img image.Image) *image.NRGBA { - src := toNRGBA(img) - srcW := src.Bounds().Max.X - srcH := src.Bounds().Max.Y - dstW := srcH - dstH := srcW - dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) - - parallel(dstH, func(partStart, partEnd int) { - - for dstY := partStart; dstY < partEnd; dstY++ { - for dstX := 0; dstX < dstW; dstX++ { - srcX := dstH - dstY - 1 - srcY := dstW - dstX - 1 - - srcOff := srcY*src.Stride + srcX*4 - dstOff := dstY*dst.Stride + dstX*4 - - copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4]) - } - } - - }) - - return dst -} diff --git a/Godeps/_workspace/src/github.com/disintegration/imaging/utils.go b/Godeps/_workspace/src/github.com/disintegration/imaging/utils.go deleted file mode 100644 index 8b1ab8adb..000000000 --- a/Godeps/_workspace/src/github.com/disintegration/imaging/utils.go +++ /dev/null @@ -1,77 +0,0 @@ -package imaging - -import ( - "math" - "runtime" - "sync" - "sync/atomic" -) - -var parallelizationEnabled = true - -// if GOMAXPROCS = 1: no goroutines used -// if GOMAXPROCS > 1: spawn N=GOMAXPROCS workers in separate goroutines -func parallel(dataSize int, fn func(partStart, partEnd int)) { - numGoroutines := 1 - partSize := dataSize - - if parallelizationEnabled { - numProcs := runtime.GOMAXPROCS(0) - if numProcs > 1 { - numGoroutines = numProcs - partSize = dataSize / (numGoroutines * 10) - if partSize < 1 { - partSize = 1 - } - } - } - - if numGoroutines == 1 { - fn(0, dataSize) - } else { - var wg sync.WaitGroup - wg.Add(numGoroutines) - idx := uint64(0) - - for p := 0; p < numGoroutines; p++ { - go func() { - defer wg.Done() - for { - partStart := int(atomic.AddUint64(&idx, uint64(partSize))) - partSize - if partStart >= dataSize { - break - } - partEnd := partStart + partSize - if partEnd > dataSize { - partEnd = dataSize - } - fn(partStart, partEnd) - } - }() - } - - wg.Wait() - } -} - -func absint(i int) int { - if i < 0 { - return -i - } - return i -} - -// clamp & round float64 to uint8 (0..255) -func clamp(v float64) uint8 { - return uint8(math.Min(math.Max(v, 0.0), 255.0) + 0.5) -} - -// clamp int32 to uint8 (0..255) -func clampint32(v int32) uint8 { - if v < 0 { - return 0 - } else if v > 255 { - return 255 - } - return uint8(v) -} |