aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/disintegration/imaging
diff options
context:
space:
mode:
authorTulir Asokan <tulir@maunium.net>2019-01-11 23:28:47 +0200
committerTulir Asokan <tulir@maunium.net>2019-01-11 23:28:47 +0200
commit331597b9f8a7942cbcb233a328301e4d5bf94fb0 (patch)
tree5ec624585ebf66c63549a098acb6f7421f1193a7 /vendor/github.com/disintegration/imaging
parent2fc3378b717f40f37f3a188b68407887242d9c06 (diff)
Switch to Go modules and make other changes
Diffstat (limited to 'vendor/github.com/disintegration/imaging')
-rw-r--r--vendor/github.com/disintegration/imaging/.travis.yml13
-rw-r--r--vendor/github.com/disintegration/imaging/LICENSE21
-rw-r--r--vendor/github.com/disintegration/imaging/README.md188
-rw-r--r--vendor/github.com/disintegration/imaging/adjust.go222
-rw-r--r--vendor/github.com/disintegration/imaging/convolution.go146
-rw-r--r--vendor/github.com/disintegration/imaging/doc.go7
-rw-r--r--vendor/github.com/disintegration/imaging/effects.go173
-rw-r--r--vendor/github.com/disintegration/imaging/histogram.go51
-rw-r--r--vendor/github.com/disintegration/imaging/io.go463
-rw-r--r--vendor/github.com/disintegration/imaging/resize.go572
-rw-r--r--vendor/github.com/disintegration/imaging/scanner.go250
-rw-r--r--vendor/github.com/disintegration/imaging/tools.go247
-rw-r--r--vendor/github.com/disintegration/imaging/transform.go271
-rw-r--r--vendor/github.com/disintegration/imaging/utils.go83
14 files changed, 0 insertions, 2707 deletions
diff --git a/vendor/github.com/disintegration/imaging/.travis.yml b/vendor/github.com/disintegration/imaging/.travis.yml
deleted file mode 100644
index 89370ed..0000000
--- a/vendor/github.com/disintegration/imaging/.travis.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-language: go
-go:
- - "1.7.x"
- - "1.8.x"
- - "1.9.x"
- - "1.10.x"
-
-before_install:
- - go get github.com/mattn/goveralls
-
-script:
- - go test -v -race -cover
- - $GOPATH/bin/goveralls -service=travis-ci
diff --git a/vendor/github.com/disintegration/imaging/LICENSE b/vendor/github.com/disintegration/imaging/LICENSE
deleted file mode 100644
index c68f7ab..0000000
--- a/vendor/github.com/disintegration/imaging/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2012-2018 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/vendor/github.com/disintegration/imaging/README.md b/vendor/github.com/disintegration/imaging/README.md
deleted file mode 100644
index c7ee30f..0000000
--- a/vendor/github.com/disintegration/imaging/README.md
+++ /dev/null
@@ -1,188 +0,0 @@
-# Imaging
-
-[![GoDoc](https://godoc.org/github.com/disintegration/imaging?status.svg)](https://godoc.org/github.com/disintegration/imaging)
-[![Build Status](https://travis-ci.org/disintegration/imaging.svg?branch=master)](https://travis-ci.org/disintegration/imaging)
-[![Coverage Status](https://coveralls.io/repos/github/disintegration/imaging/badge.svg?branch=master&service=github)](https://coveralls.io/github/disintegration/imaging?branch=master)
-[![Go Report Card](https://goreportcard.com/badge/github.com/disintegration/imaging)](https://goreportcard.com/report/github.com/disintegration/imaging)
-
-Package imaging provides basic image processing functions (resize, rotate, crop, brightness/contrast adjustments, etc.).
-
-All the image processing functions provided by the package accept 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
-
- 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, 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:
-
-![srcImage](testdata/branches.png)
-
-The same image resized from 600x400px to 150x100px using different resampling filters.
-From faster (lower quality) to slower (higher quality):
-
-Filter | Resize result
---------------------------|---------------------------------------------
-`imaging.NearestNeighbor` | ![dstImage](testdata/out_resize_nearest.png)
-`imaging.Linear` | ![dstImage](testdata/out_resize_linear.png)
-`imaging.CatmullRom` | ![dstImage](testdata/out_resize_catrom.png)
-`imaging.Lanczos` | ![dstImage](testdata/out_resize_lanczos.png)
-
-
-### 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](testdata/flowers_small.png) | ![dstImage](testdata/out_blur_0.5.png) | ![dstImage](testdata/out_blur_1.5.png)
-
-### Sharpening
-
-```go
-dstImage := imaging.Sharpen(srcImage, 0.5)
-```
-
-`Sharpen` uses gaussian function internally. Sigma parameter allows to control the strength of the sharpening effect.
-
-Original image | Sigma = 0.5 | Sigma = 1.5
------------------------------------|-------------------------------------------|------------------------------------------
-![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_sharpen_0.5.png) | ![dstImage](testdata/out_sharpen_1.5.png)
-
-### Gamma correction
-
-```go
-dstImage := imaging.AdjustGamma(srcImage, 0.75)
-```
-
-Original image | Gamma = 0.75 | Gamma = 1.25
------------------------------------|------------------------------------------|-----------------------------------------
-![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_gamma_0.75.png) | ![dstImage](testdata/out_gamma_1.25.png)
-
-### Contrast adjustment
-
-```go
-dstImage := imaging.AdjustContrast(srcImage, 20)
-```
-
-Original image | Contrast = 15 | Contrast = -15
------------------------------------|--------------------------------------------|-------------------------------------------
-![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_contrast_p15.png) | ![dstImage](testdata/out_contrast_m15.png)
-
-### Brightness adjustment
-
-```go
-dstImage := imaging.AdjustBrightness(srcImage, 20)
-```
-
-Original image | Brightness = 10 | Brightness = -10
------------------------------------|----------------------------------------------|---------------------------------------------
-![srcImage](testdata/flowers_small.png) | ![dstImage](testdata/out_brightness_p10.png) | ![dstImage](testdata/out_brightness_m10.png)
-
-## Example code
-
-```go
-package main
-
-import (
- "image"
- "image/color"
- "log"
-
- "github.com/disintegration/imaging"
-)
-
-func main() {
- // Open a test image.
- src, err := imaging.Open("testdata/flowers.png")
- if err != nil {
- log.Fatalf("failed to open image: %v", err)
- }
-
- // Crop the original image to 300x300px size using the center anchor.
- src = imaging.CropAnchor(src, 300, 300, imaging.Center)
-
- // Resize the cropped image to width = 200px preserving the aspect ratio.
- src = imaging.Resize(src, 200, 0, imaging.Lanczos)
-
- // Create a blurred version of the image.
- img1 := imaging.Blur(src, 5)
-
- // Create a grayscale version of the image with higher contrast and sharpness.
- img2 := imaging.Grayscale(src)
- img2 = imaging.AdjustContrast(img2, 20)
- img2 = imaging.Sharpen(img2, 2)
-
- // Create an inverted version of the image.
- img3 := imaging.Invert(src)
-
- // Create an embossed version of the image using a convolution filter.
- img4 := imaging.Convolve3x3(
- src,
- [9]float64{
- -1, -1, 0,
- -1, 1, 1,
- 0, 1, 1,
- },
- nil,
- )
-
- // Create a new image and paste the four produced images into it.
- dst := imaging.New(400, 400, color.NRGBA{0, 0, 0, 0})
- dst = imaging.Paste(dst, img1, image.Pt(0, 0))
- dst = imaging.Paste(dst, img2, image.Pt(0, 200))
- dst = imaging.Paste(dst, img3, image.Pt(200, 0))
- dst = imaging.Paste(dst, img4, image.Pt(200, 200))
-
- // Save the resulting image as JPEG.
- err = imaging.Save(dst, "testdata/out_example.jpg")
- if err != nil {
- log.Fatalf("failed to save image: %v", err)
- }
-}
-```
-
-Output:
-
-![dstImage](testdata/out_example.jpg) \ No newline at end of file
diff --git a/vendor/github.com/disintegration/imaging/adjust.go b/vendor/github.com/disintegration/imaging/adjust.go
deleted file mode 100644
index fb3a9ce..0000000
--- a/vendor/github.com/disintegration/imaging/adjust.go
+++ /dev/null
@@ -1,222 +0,0 @@
-package imaging
-
-import (
- "image"
- "image/color"
- "math"
-)
-
-// Grayscale produces a grayscale version of the image.
-func Grayscale(img image.Image) *image.NRGBA {
- src := newScanner(img)
- dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
- parallel(0, src.h, func(ys <-chan int) {
- for y := range ys {
- i := y * dst.Stride
- src.scan(0, y, src.w, y+1, dst.Pix[i:i+src.w*4])
- for x := 0; x < src.w; x++ {
- r := dst.Pix[i+0]
- g := dst.Pix[i+1]
- b := dst.Pix[i+2]
- f := 0.299*float64(r) + 0.587*float64(g) + 0.114*float64(b)
- y := uint8(f + 0.5)
- dst.Pix[i+0] = y
- dst.Pix[i+1] = y
- dst.Pix[i+2] = y
- i += 4
- }
- }
- })
- return dst
-}
-
-// Invert produces an inverted (negated) version of the image.
-func Invert(img image.Image) *image.NRGBA {
- src := newScanner(img)
- dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
- parallel(0, src.h, func(ys <-chan int) {
- for y := range ys {
- i := y * dst.Stride
- src.scan(0, y, src.w, y+1, dst.Pix[i:i+src.w*4])
- for x := 0; x < src.w; x++ {
- dst.Pix[i+0] = 255 - dst.Pix[i+0]
- dst.Pix[i+1] = 255 - dst.Pix[i+1]
- dst.Pix[i+2] = 255 - dst.Pix[i+2]
- i += 4
- }
- }
- })
- return dst
-}
-
-// 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 gray 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
- }
- }
-
- return adjustLUT(img, lut)
-}
-
-// 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)
- }
-
- return adjustLUT(img, lut)
-}
-
-// 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)
- }
-
- return adjustLUT(img, lut)
-}
-
-// 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)
- }
- }
-
- return adjustLUT(img, lut)
-}
-
-func sigmoid(a, b, x float64) float64 {
- return 1 / (1 + math.Exp(b*(a-x)))
-}
-
-// adjustLUT applies the given lookup table to the colors of the image.
-func adjustLUT(img image.Image, lut []uint8) *image.NRGBA {
- src := newScanner(img)
- dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
- parallel(0, src.h, func(ys <-chan int) {
- for y := range ys {
- i := y * dst.Stride
- src.scan(0, y, src.w, y+1, dst.Pix[i:i+src.w*4])
- for x := 0; x < src.w; x++ {
- dst.Pix[i+0] = lut[dst.Pix[i+0]]
- dst.Pix[i+1] = lut[dst.Pix[i+1]]
- dst.Pix[i+2] = lut[dst.Pix[i+2]]
- i += 4
- }
- }
- })
- return dst
-}
-
-// 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 := newScanner(img)
- dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
- parallel(0, src.h, func(ys <-chan int) {
- for y := range ys {
- i := y * dst.Stride
- src.scan(0, y, src.w, y+1, dst.Pix[i:i+src.w*4])
- for x := 0; x < src.w; x++ {
- r := dst.Pix[i+0]
- g := dst.Pix[i+1]
- b := dst.Pix[i+2]
- a := dst.Pix[i+3]
- c := fn(color.NRGBA{r, g, b, a})
- dst.Pix[i+0] = c.R
- dst.Pix[i+1] = c.G
- dst.Pix[i+2] = c.B
- dst.Pix[i+3] = c.A
- i += 4
- }
- }
- })
- return dst
-}
diff --git a/vendor/github.com/disintegration/imaging/convolution.go b/vendor/github.com/disintegration/imaging/convolution.go
deleted file mode 100644
index 9e6404d..0000000
--- a/vendor/github.com/disintegration/imaging/convolution.go
+++ /dev/null
@@ -1,146 +0,0 @@
-package imaging
-
-import (
- "image"
-)
-
-// ConvolveOptions are convolution parameters.
-type ConvolveOptions struct {
- // If Normalize is true the kernel is normalized before convolution.
- Normalize bool
-
- // If Abs is true the absolute value of each color channel is taken after convolution.
- Abs bool
-
- // Bias is added to each color channel value after convolution.
- Bias int
-}
-
-// Convolve3x3 convolves the image with the specified 3x3 convolution kernel.
-// Default parameters are used if a nil *ConvolveOptions is passed.
-func Convolve3x3(img image.Image, kernel [9]float64, options *ConvolveOptions) *image.NRGBA {
- return convolve(img, kernel[:], options)
-}
-
-// Convolve5x5 convolves the image with the specified 5x5 convolution kernel.
-// Default parameters are used if a nil *ConvolveOptions is passed.
-func Convolve5x5(img image.Image, kernel [25]float64, options *ConvolveOptions) *image.NRGBA {
- return convolve(img, kernel[:], options)
-}
-
-func convolve(img image.Image, kernel []float64, options *ConvolveOptions) *image.NRGBA {
- src := toNRGBA(img)
- w := src.Bounds().Max.X
- h := src.Bounds().Max.Y
- dst := image.NewNRGBA(image.Rect(0, 0, w, h))
-
- if w < 1 || h < 1 {
- return dst
- }
-
- if options == nil {
- options = &ConvolveOptions{}
- }
-
- if options.Normalize {
- normalizeKernel(kernel)
- }
-
- type coef struct {
- x, y int
- k float64
- }
- var coefs []coef
- var m int
-
- switch len(kernel) {
- case 9:
- m = 1
- case 25:
- m = 2
- }
-
- i := 0
- for y := -m; y <= m; y++ {
- for x := -m; x <= m; x++ {
- if kernel[i] != 0 {
- coefs = append(coefs, coef{x: x, y: y, k: kernel[i]})
- }
- i++
- }
- }
-
- parallel(0, h, func(ys <-chan int) {
- for y := range ys {
- for x := 0; x < w; x++ {
- var r, g, b float64
- for _, c := range coefs {
- ix := x + c.x
- if ix < 0 {
- ix = 0
- } else if ix >= w {
- ix = w - 1
- }
-
- iy := y + c.y
- if iy < 0 {
- iy = 0
- } else if iy >= h {
- iy = h - 1
- }
-
- off := iy*src.Stride + ix*4
- r += float64(src.Pix[off+0]) * c.k
- g += float64(src.Pix[off+1]) * c.k
- b += float64(src.Pix[off+2]) * c.k
- }
-
- if options.Abs {
- if r < 0 {
- r = -r
- }
- if g < 0 {
- g = -g
- }
- if b < 0 {
- b = -b
- }
- }
-
- if options.Bias != 0 {
- r += float64(options.Bias)
- g += float64(options.Bias)
- b += float64(options.Bias)
- }
-
- srcOff := y*src.Stride + x*4
- dstOff := y*dst.Stride + x*4
- dst.Pix[dstOff+0] = clamp(r)
- dst.Pix[dstOff+1] = clamp(g)
- dst.Pix[dstOff+2] = clamp(b)
- dst.Pix[dstOff+3] = src.Pix[srcOff+3]
- }
- }
- })
-
- return dst
-}
-
-func normalizeKernel(kernel []float64) {
- var sum, sumpos float64
- for i := range kernel {
- sum += kernel[i]
- if kernel[i] > 0 {
- sumpos += kernel[i]
- }
- }
- if sum != 0 {
- for i := range kernel {
- kernel[i] /= sum
- }
- } else if sumpos != 0 {
- for i := range kernel {
- kernel[i] /= sumpos
- }
- }
-}
diff --git a/vendor/github.com/disintegration/imaging/doc.go b/vendor/github.com/disintegration/imaging/doc.go
deleted file mode 100644
index 5d59b46..0000000
--- a/vendor/github.com/disintegration/imaging/doc.go
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
-Package imaging provides basic image processing functions (resize, rotate, crop, brightness/contrast adjustments, etc.).
-
-All the image processing functions provided by the package accept 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
diff --git a/vendor/github.com/disintegration/imaging/effects.go b/vendor/github.com/disintegration/imaging/effects.go
deleted file mode 100644
index 149cfeb..0000000
--- a/vendor/github.com/disintegration/imaging/effects.go
+++ /dev/null
@@ -1,173 +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 {
- return Clone(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)
- }
-
- return blurVertical(blurHorizontal(img, kernel), kernel)
-}
-
-func blurHorizontal(img image.Image, kernel []float64) *image.NRGBA {
- src := newScanner(img)
- dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
- radius := len(kernel) - 1
-
- parallel(0, src.h, func(ys <-chan int) {
- scanLine := make([]uint8, src.w*4)
- scanLineF := make([]float64, len(scanLine))
- for y := range ys {
- src.scan(0, y, src.w, y+1, scanLine)
- for i, v := range scanLine {
- scanLineF[i] = float64(v)
- }
- for x, idx := 0, 0; x < src.w; x, idx = x+1, idx+4 {
- min := x - radius
- if min < 0 {
- min = 0
- }
- max := x + radius
- if max > src.w-1 {
- max = src.w - 1
- }
-
- var r, g, b, a, wsum float64
- for ix := min; ix <= max; ix++ {
- i := ix * 4
- weight := kernel[absint(x-ix)]
- wsum += weight
- wa := scanLineF[i+3] * weight
- r += scanLineF[i+0] * wa
- g += scanLineF[i+1] * wa
- b += scanLineF[i+2] * wa
- a += wa
- }
- if a != 0 {
- r /= a
- g /= a
- b /= a
- }
-
- scanLine[idx+0] = clamp(r)
- scanLine[idx+1] = clamp(g)
- scanLine[idx+2] = clamp(b)
- scanLine[idx+3] = clamp(a / wsum)
- }
- copy(dst.Pix[y*dst.Stride:], scanLine)
- }
- })
-
- return dst
-}
-
-func blurVertical(img image.Image, kernel []float64) *image.NRGBA {
- src := newScanner(img)
- dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
- radius := len(kernel) - 1
-
- parallel(0, src.w, func(xs <-chan int) {
- scanLine := make([]uint8, src.h*4)
- scanLineF := make([]float64, len(scanLine))
- for x := range xs {
- src.scan(x, 0, x+1, src.h, scanLine)
- for i, v := range scanLine {
- scanLineF[i] = float64(v)
- }
- for y := 0; y < src.h; y++ {
- min := y - radius
- if min < 0 {
- min = 0
- }
- max := y + radius
- if max > src.h-1 {
- max = src.h - 1
- }
-
- var r, g, b, a, wsum float64
- for iy := min; iy <= max; iy++ {
- i := iy * 4
- weight := kernel[absint(y-iy)]
- wsum += weight
- wa := scanLineF[i+3] * weight
- r += scanLineF[i+0] * wa
- g += scanLineF[i+1] * wa
- b += scanLineF[i+2] * wa
- a += wa
- }
- if a != 0 {
- r /= a
- g /= a
- b /= a
- }
-
- j := y*dst.Stride + x*4
- dst.Pix[j+0] = clamp(r)
- dst.Pix[j+1] = clamp(g)
- dst.Pix[j+2] = clamp(b)
- dst.Pix[j+3] = clamp(a / wsum)
- }
- }
- })
-
- 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 {
- return Clone(img)
- }
-
- src := newScanner(img)
- dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
- blurred := Blur(img, sigma)
-
- parallel(0, src.h, func(ys <-chan int) {
- scanLine := make([]uint8, src.w*4)
- for y := range ys {
- src.scan(0, y, src.w, y+1, scanLine)
- j := y * dst.Stride
- for i := 0; i < src.w*4; i++ {
- val := int(scanLine[i])<<1 - int(blurred.Pix[j])
- if val < 0 {
- val = 0
- } else if val > 0xff {
- val = 0xff
- }
- dst.Pix[j] = uint8(val)
- j++
- }
- }
- })
-
- return dst
-}
diff --git a/vendor/github.com/disintegration/imaging/histogram.go b/vendor/github.com/disintegration/imaging/histogram.go
deleted file mode 100644
index 5bcb001..0000000
--- a/vendor/github.com/disintegration/imaging/histogram.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package imaging
-
-import (
- "image"
- "sync"
-)
-
-// Histogram returns a normalized histogram of an image.
-//
-// Resulting histogram is represented as an array of 256 floats, where
-// histogram[i] is a probability of a pixel being of a particular luminance i.
-func Histogram(img image.Image) [256]float64 {
- var mu sync.Mutex
- var histogram [256]float64
- var total float64
-
- src := newScanner(img)
- if src.w == 0 || src.h == 0 {
- return histogram
- }
-
- parallel(0, src.h, func(ys <-chan int) {
- var tmpHistogram [256]float64
- var tmpTotal float64
- scanLine := make([]uint8, src.w*4)
- for y := range ys {
- src.scan(0, y, src.w, y+1, scanLine)
- i := 0
- for x := 0; x < src.w; x++ {
- r := scanLine[i+0]
- g := scanLine[i+1]
- b := scanLine[i+2]
- y := 0.299*float32(r) + 0.587*float32(g) + 0.114*float32(b)
- tmpHistogram[int(y+0.5)]++
- tmpTotal++
- i += 4
- }
- }
- mu.Lock()
- for i := 0; i < 256; i++ {
- histogram[i] += tmpHistogram[i]
- }
- total += tmpTotal
- mu.Unlock()
- })
-
- for i := 0; i < 256; i++ {
- histogram[i] = histogram[i] / total
- }
- return histogram
-}
diff --git a/vendor/github.com/disintegration/imaging/io.go b/vendor/github.com/disintegration/imaging/io.go
deleted file mode 100644
index 557bf2f..0000000
--- a/vendor/github.com/disintegration/imaging/io.go
+++ /dev/null
@@ -1,463 +0,0 @@
-package imaging
-
-import (
- "encoding/binary"
- "errors"
- "image"
- "image/draw"
- "image/gif"
- "image/jpeg"
- "image/png"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
-
- "golang.org/x/image/bmp"
- "golang.org/x/image/tiff"
-)
-
-// Format is an image file format.
-type Format int
-
-// Image file formats.
-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 formatFromExt = map[string]Format{
- "jpg": JPEG,
- "jpeg": JPEG,
- "png": PNG,
- "tif": TIFF,
- "tiff": TIFF,
- "bmp": BMP,
- "gif": GIF,
-}
-
-// FormatFromExtension parses image format from extension:
-// "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported.
-func FormatFromExtension(ext string) (Format, error) {
- if f, ok := formatFromExt[strings.ToLower(strings.TrimPrefix(ext, "."))]; ok {
- return f, nil
- }
- return -1, ErrUnsupportedFormat
-}
-
-// FormatFromFilename parses image format from filename extension:
-// "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported.
-func FormatFromFilename(filename string) (Format, error) {
- ext := filepath.Ext(filename)
- return FormatFromExtension(ext)
-}
-
-var (
- // ErrUnsupportedFormat means the given image format (or file extension) is unsupported.
- ErrUnsupportedFormat = errors.New("imaging: unsupported image format")
-)
-
-type fileSystem interface {
- Create(string) (io.WriteCloser, error)
- Open(string) (io.ReadCloser, error)
-}
-
-type localFS struct{}
-
-func (localFS) Create(name string) (io.WriteCloser, error) { return os.Create(name) }
-func (localFS) Open(name string) (io.ReadCloser, error) { return os.Open(name) }
-
-var fs fileSystem = localFS{}
-
-type decodeConfig struct {
- autoOrientation bool
-}
-
-var defaultDecodeConfig = decodeConfig{
- autoOrientation: false,
-}
-
-// DecodeOption sets an optional parameter for the Decode and Open functions.
-type DecodeOption func(*decodeConfig)
-
-// AutoOrientation returns a DecodeOption that sets the auto-orientation mode.
-// If auto-orientation is enabled, the image will be transformed after decoding
-// according to the EXIF orientation tag (if present). By default it's disabled.
-func AutoOrientation(enabled bool) DecodeOption {
- return func(c *decodeConfig) {
- c.autoOrientation = enabled
- }
-}
-
-// Decode reads an image from r.
-func Decode(r io.Reader, opts ...DecodeOption) (image.Image, error) {
- cfg := defaultDecodeConfig
- for _, option := range opts {
- option(&cfg)
- }
-
- if !cfg.autoOrientation {
- img, _, err := image.Decode(r)
- return img, err
- }
-
- var orient orientation
- pr, pw := io.Pipe()
- r = io.TeeReader(r, pw)
- done := make(chan struct{})
- go func() {
- defer close(done)
- orient = readOrientation(pr)
- io.Copy(ioutil.Discard, pr)
- }()
-
- img, _, err := image.Decode(r)
- pw.Close()
- <-done
- if err != nil {
- return nil, err
- }
-
- return fixOrientation(img, orient), nil
-}
-
-// Open loads an image from file.
-//
-// Examples:
-//
-// // Load an image from file.
-// img, err := imaging.Open("test.jpg")
-//
-// // Load an image and transform it depending on the EXIF orientation tag (if present).
-// img, err := imaging.Open("test.jpg", imaging.AutoOrientation(true))
-//
-func Open(filename string, opts ...DecodeOption) (image.Image, error) {
- file, err := fs.Open(filename)
- if err != nil {
- return nil, err
- }
- defer file.Close()
- return Decode(file, opts...)
-}
-
-type encodeConfig struct {
- jpegQuality int
- gifNumColors int
- gifQuantizer draw.Quantizer
- gifDrawer draw.Drawer
- pngCompressionLevel png.CompressionLevel
-}
-
-var defaultEncodeConfig = encodeConfig{
- jpegQuality: 95,
- gifNumColors: 256,
- gifQuantizer: nil,
- gifDrawer: nil,
- pngCompressionLevel: png.DefaultCompression,
-}
-
-// EncodeOption sets an optional parameter for the Encode and Save functions.
-type EncodeOption func(*encodeConfig)
-
-// JPEGQuality returns an EncodeOption that sets the output JPEG quality.
-// Quality ranges from 1 to 100 inclusive, higher is better. Default is 95.
-func JPEGQuality(quality int) EncodeOption {
- return func(c *encodeConfig) {
- c.jpegQuality = quality
- }
-}
-
-// GIFNumColors returns an EncodeOption that sets the maximum number of colors
-// used in the GIF-encoded image. It ranges from 1 to 256. Default is 256.
-func GIFNumColors(numColors int) EncodeOption {
- return func(c *encodeConfig) {
- c.gifNumColors = numColors
- }
-}
-
-// GIFQuantizer returns an EncodeOption that sets the quantizer that is used to produce
-// a palette of the GIF-encoded image.
-func GIFQuantizer(quantizer draw.Quantizer) EncodeOption {
- return func(c *encodeConfig) {
- c.gifQuantizer = quantizer
- }
-}
-
-// GIFDrawer returns an EncodeOption that sets the drawer that is used to convert
-// the source image to the desired palette of the GIF-encoded image.
-func GIFDrawer(drawer draw.Drawer) EncodeOption {
- return func(c *encodeConfig) {
- c.gifDrawer = drawer
- }
-}
-
-// PNGCompressionLevel returns an EncodeOption that sets the compression level
-// of the PNG-encoded image. Default is png.DefaultCompression.
-func PNGCompressionLevel(level png.CompressionLevel) EncodeOption {
- return func(c *encodeConfig) {
- c.pngCompressionLevel = level
- }
-}
-
-// 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, opts ...EncodeOption) error {
- cfg := defaultEncodeConfig
- for _, option := range opts {
- option(&cfg)
- }
-
- 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: cfg.jpegQuality})
- } else {
- err = jpeg.Encode(w, img, &jpeg.Options{Quality: cfg.jpegQuality})
- }
-
- case PNG:
- enc := png.Encoder{CompressionLevel: cfg.pngCompressionLevel}
- err = enc.Encode(w, img)
-
- case GIF:
- err = gif.Encode(w, img, &gif.Options{
- NumColors: cfg.gifNumColors,
- Quantizer: cfg.gifQuantizer,
- Drawer: cfg.gifDrawer,
- })
-
- 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.
-//
-// Examples:
-//
-// // Save the image as PNG.
-// err := imaging.Save(img, "out.png")
-//
-// // Save the image as JPEG with optional quality parameter set to 80.
-// err := imaging.Save(img, "out.jpg", imaging.JPEGQuality(80))
-//
-func Save(img image.Image, filename string, opts ...EncodeOption) (err error) {
- f, err := FormatFromFilename(filename)
- if err != nil {
- return err
- }
- file, err := fs.Create(filename)
- if err != nil {
- return err
- }
-
- defer func() {
- cerr := file.Close()
- if err == nil {
- err = cerr
- }
- }()
-
- return Encode(file, img, f, opts...)
-}
-
-// orientation is an EXIF flag that specifies the transformation
-// that should be applied to image to display it correctly.
-type orientation int
-
-const (
- orientationUnspecified = 0
- orientationNormal = 1
- orientationFlipH = 2
- orientationRotate180 = 3
- orientationFlipV = 4
- orientationTranspose = 5
- orientationRotate270 = 6
- orientationTransverse = 7
- orientationRotate90 = 8
-)
-
-// readOrientation tries to read the orientation EXIF flag from image data in r.
-// If the EXIF data block is not found or the orientation flag is not found
-// or any other error occures while reading the data, it returns the
-// orientationUnspecified (0) value.
-func readOrientation(r io.Reader) orientation {
- const (
- markerSOI = 0xffd8
- markerAPP1 = 0xffe1
- exifHeader = 0x45786966
- byteOrderBE = 0x4d4d
- byteOrderLE = 0x4949
- orientationTag = 0x0112
- )
-
- // Check if JPEG SOI marker is present.
- var soi uint16
- if err := binary.Read(r, binary.BigEndian, &soi); err != nil {
- return orientationUnspecified
- }
- if soi != markerSOI {
- return orientationUnspecified // Missing JPEG SOI marker.
- }
-
- // Find JPEG APP1 marker.
- for {
- var marker, size uint16
- if err := binary.Read(r, binary.BigEndian, &marker); err != nil {
- return orientationUnspecified
- }
- if err := binary.Read(r, binary.BigEndian, &size); err != nil {
- return orientationUnspecified
- }
- if marker>>8 != 0xff {
- return orientationUnspecified // Invalid JPEG marker.
- }
- if marker == markerAPP1 {
- break
- }
- if size < 2 {
- return orientationUnspecified // Invalid block size.
- }
- if _, err := io.CopyN(ioutil.Discard, r, int64(size-2)); err != nil {
- return orientationUnspecified
- }
- }
-
- // Check if EXIF header is present.
- var header uint32
- if err := binary.Read(r, binary.BigEndian, &header); err != nil {
- return orientationUnspecified
- }
- if header != exifHeader {
- return orientationUnspecified
- }
- if _, err := io.CopyN(ioutil.Discard, r, 2); err != nil {
- return orientationUnspecified
- }
-
- // Read byte order information.
- var (
- byteOrderTag uint16
- byteOrder binary.ByteOrder
- )
- if err := binary.Read(r, binary.BigEndian, &byteOrderTag); err != nil {
- return orientationUnspecified
- }
- switch byteOrderTag {
- case byteOrderBE:
- byteOrder = binary.BigEndian
- case byteOrderLE:
- byteOrder = binary.LittleEndian
- default:
- return orientationUnspecified // Invalid byte order flag.
- }
- if _, err := io.CopyN(ioutil.Discard, r, 2); err != nil {
- return orientationUnspecified
- }
-
- // Skip the EXIF offset.
- var offset uint32
- if err := binary.Read(r, byteOrder, &offset); err != nil {
- return orientationUnspecified
- }
- if offset < 8 {
- return orientationUnspecified // Invalid offset value.
- }
- if _, err := io.CopyN(ioutil.Discard, r, int64(offset-8)); err != nil {
- return orientationUnspecified
- }
-
- // Read the number of tags.
- var numTags uint16
- if err := binary.Read(r, byteOrder, &numTags); err != nil {
- return orientationUnspecified
- }
-
- // Find the orientation tag.
- for i := 0; i < int(numTags); i++ {
- var tag uint16
- if err := binary.Read(r, byteOrder, &tag); err != nil {
- return orientationUnspecified
- }
- if tag != orientationTag {
- if _, err := io.CopyN(ioutil.Discard, r, 10); err != nil {
- return orientationUnspecified
- }
- continue
- }
- if _, err := io.CopyN(ioutil.Discard, r, 6); err != nil {
- return orientationUnspecified
- }
- var val uint16
- if err := binary.Read(r, byteOrder, &val); err != nil {
- return orientationUnspecified
- }
- if val < 1 || val > 8 {
- return orientationUnspecified // Invalid tag value.
- }
- return orientation(val)
- }
- return orientationUnspecified // Missing orientation tag.
-}
-
-// fixOrientation applies a transform to img corresponding to the given orientation flag.
-func fixOrientation(img image.Image, o orientation) image.Image {
- switch o {
- case orientationNormal:
- case orientationFlipH:
- img = FlipH(img)
- case orientationFlipV:
- img = FlipV(img)
- case orientationRotate90:
- img = Rotate90(img)
- case orientationRotate180:
- img = Rotate180(img)
- case orientationRotate270:
- img = Rotate270(img)
- case orientationTranspose:
- img = Transpose(img)
- case orientationTransverse:
- img = Transverse(img)
- }
- return img
-}
diff --git a/vendor/github.com/disintegration/imaging/resize.go b/vendor/github.com/disintegration/imaging/resize.go
deleted file mode 100644
index 97f498a..0000000
--- a/vendor/github.com/disintegration/imaging/resize.go
+++ /dev/null
@@ -1,572 +0,0 @@
-package imaging
-
-import (
- "image"
- "math"
-)
-
-type indexWeight struct {
- index int
- weight float64
-}
-
-func precomputeWeights(dstSize, srcSize int, filter ResampleFilter) [][]indexWeight {
- du := float64(srcSize) / float64(dstSize)
- scale := du
- if scale < 1.0 {
- scale = 1.0
- }
- ru := math.Ceil(scale * filter.Support)
-
- out := make([][]indexWeight, dstSize)
- tmp := make([]indexWeight, 0, dstSize*int(ru+2)*2)
-
- for v := 0; v < dstSize; v++ {
- fu := (float64(v)+0.5)*du - 0.5
-
- begin := int(math.Ceil(fu - ru))
- if begin < 0 {
- begin = 0
- }
- end := int(math.Floor(fu + ru))
- if end > srcSize-1 {
- end = srcSize - 1
- }
-
- var sum float64
- for u := begin; u <= end; u++ {
- w := filter.Kernel((float64(u) - fu) / scale)
- if w != 0 {
- sum += w
- tmp = append(tmp, indexWeight{index: u, weight: w})
- }
- }
- if sum != 0 {
- for i := range tmp {
- tmp[i].weight /= sum
- }
- }
-
- out[v] = tmp
- tmp = tmp[len(tmp):]
- }
-
- 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{}
- }
-
- srcW := img.Bounds().Dx()
- srcH := img.Bounds().Dy()
- 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)))
- }
-
- if filter.Support <= 0 {
- // Nearest-neighbor special case.
- return resizeNearest(img, dstW, dstH)
- }
-
- if srcW != dstW && srcH != dstH {
- return resizeVertical(resizeHorizontal(img, dstW, filter), dstH, filter)
- }
- if srcW != dstW {
- return resizeHorizontal(img, dstW, filter)
- }
- if srcH != dstH {
- return resizeVertical(img, dstH, filter)
- }
- return Clone(img)
-}
-
-func resizeHorizontal(img image.Image, width int, filter ResampleFilter) *image.NRGBA {
- src := newScanner(img)
- dst := image.NewNRGBA(image.Rect(0, 0, width, src.h))
- weights := precomputeWeights(width, src.w, filter)
- parallel(0, src.h, func(ys <-chan int) {
- scanLine := make([]uint8, src.w*4)
- for y := range ys {
- src.scan(0, y, src.w, y+1, scanLine)
- j0 := y * dst.Stride
- for x := 0; x < width; x++ {
- var r, g, b, a float64
- for _, w := range weights[x] {
- i := w.index * 4
- aw := float64(scanLine[i+3]) * w.weight
- r += float64(scanLine[i+0]) * aw
- g += float64(scanLine[i+1]) * aw
- b += float64(scanLine[i+2]) * aw
- a += aw
- }
- if a != 0 {
- aInv := 1 / a
- j := j0 + x*4
- dst.Pix[j+0] = clamp(r * aInv)
- dst.Pix[j+1] = clamp(g * aInv)
- dst.Pix[j+2] = clamp(b * aInv)
- dst.Pix[j+3] = clamp(a)
- }
- }
- }
- })
- return dst
-}
-
-func resizeVertical(img image.Image, height int, filter ResampleFilter) *image.NRGBA {
- src := newScanner(img)
- dst := image.NewNRGBA(image.Rect(0, 0, src.w, height))
- weights := precomputeWeights(height, src.h, filter)
- parallel(0, src.w, func(xs <-chan int) {
- scanLine := make([]uint8, src.h*4)
- for x := range xs {
- src.scan(x, 0, x+1, src.h, scanLine)
- for y := 0; y < height; y++ {
- var r, g, b, a float64
- for _, w := range weights[y] {
- i := w.index * 4
- aw := float64(scanLine[i+3]) * w.weight
- r += float64(scanLine[i+0]) * aw
- g += float64(scanLine[i+1]) * aw
- b += float64(scanLine[i+2]) * aw
- a += aw
- }
- if a != 0 {
- aInv := 1 / a
- j := y*dst.Stride + x*4
- dst.Pix[j+0] = clamp(r * aInv)
- dst.Pix[j+1] = clamp(g * aInv)
- dst.Pix[j+2] = clamp(b * aInv)
- dst.Pix[j+3] = clamp(a)
- }
- }
- }
- })
- return dst
-}
-
-// resizeNearest is a fast nearest-neighbor resize, no filtering.
-func resizeNearest(img image.Image, width, height int) *image.NRGBA {
- dst := image.NewNRGBA(image.Rect(0, 0, width, height))
- dx := float64(img.Bounds().Dx()) / float64(width)
- dy := float64(img.Bounds().Dy()) / float64(height)
-
- if dx > 1 && dy > 1 {
- src := newScanner(img)
- parallel(0, height, func(ys <-chan int) {
- for y := range ys {
- srcY := int((float64(y) + 0.5) * dy)
- dstOff := y * dst.Stride
- for x := 0; x < width; x++ {
- srcX := int((float64(x) + 0.5) * dx)
- src.scan(srcX, srcY, srcX+1, srcY+1, dst.Pix[dstOff:dstOff+4])
- dstOff += 4
- }
- }
- })
- } else {
- src := toNRGBA(img)
- parallel(0, height, func(ys <-chan int) {
- for y := range ys {
- srcY := int((float64(y) + 0.5) * dy)
- srcOff0 := srcY * src.Stride
- dstOff := y * dst.Stride
- for x := 0; x < width; x++ {
- srcX := int((float64(x) + 0.5) * dx)
- srcOff := srcOff0 + srcX*4
- copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
- dstOff += 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)
-}
-
-// ResampleFilter is a resampling filter struct. It can be used to define custom filters.
-//
-// Supported resample filters: NearestNeighbor, Box, Linear, Hermite, MitchellNetravali,
-// CatmullRom, BSpline, Gaussian, Lanczos, Hann, Hamming, Blackman, Bartlett, Welch, Cosine.
-//
-// General filter recommendations:
-//
-// - Lanczos
-// High-quality resampling filter for photographic images yielding sharp results.
-// 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 artifacts 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 averaging filter appropriate for downscaling.
-// When upscaling it's similar to NearestNeighbor.
-//
-// - NearestNeighbor
-// Fastest resampling filter, no antialiasing.
-//
-type ResampleFilter struct {
- Support float64
- Kernel func(float64) float64
-}
-
-// NearestNeighbor is a 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
-
-// MitchellNetravali is Mitchell-Netravali cubic filter (BC-spline; B=1/3; C=1/3).
-var MitchellNetravali ResampleFilter
-
-// CatmullRom is a Catmull-Rom - sharp cubic filter (BC-spline; B=0; C=0.5).
-var CatmullRom ResampleFilter
-
-// BSpline is a smooth cubic filter (BC-spline; B=1; C=0).
-var BSpline ResampleFilter
-
-// Gaussian is a Gaussian blurring Filter.
-var Gaussian ResampleFilter
-
-// Bartlett is a Bartlett-windowed sinc filter (3 lobes).
-var Bartlett ResampleFilter
-
-// Lanczos filter (3 lobes).
-var Lanczos ResampleFilter
-
-// Hann is a Hann-windowed sinc filter (3 lobes).
-var Hann ResampleFilter
-
-// Hamming is a Hamming-windowed sinc filter (3 lobes).
-var Hamming ResampleFilter
-
-// Blackman is a Blackman-windowed sinc filter (3 lobes).
-var Blackman ResampleFilter
-
-// Welch is a Welch-windowed sinc filter (parabolic window, 3 lobes).
-var Welch ResampleFilter
-
-// Cosine is a Cosine-windowed sinc filter (3 lobes).
-var Cosine ResampleFilter
-
-func bcspline(x, b, c float64) float64 {
- var y float64
- x = math.Abs(x)
- if x < 1.0 {
- y = ((12-9*b-6*c)*x*x*x + (-18+12*b+6*c)*x*x + (6 - 2*b)) / 6
- } else if x < 2.0 {
- y = ((-b-6*c)*x*x*x + (6*b+30*c)*x*x + (-12*b-48*c)*x + (8*b + 24*c)) / 6
- }
- return y
-}
-
-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/vendor/github.com/disintegration/imaging/scanner.go b/vendor/github.com/disintegration/imaging/scanner.go
deleted file mode 100644
index c4dbfe1..0000000
--- a/vendor/github.com/disintegration/imaging/scanner.go
+++ /dev/null
@@ -1,250 +0,0 @@
-package imaging
-
-import (
- "image"
- "image/color"
-)
-
-type scanner struct {
- image image.Image
- w, h int
- palette []color.NRGBA
-}
-
-func newScanner(img image.Image) *scanner {
- s := &scanner{
- image: img,
- w: img.Bounds().Dx(),
- h: img.Bounds().Dy(),
- }
- if img, ok := img.(*image.Paletted); ok {
- s.palette = make([]color.NRGBA, len(img.Palette))
- for i := 0; i < len(img.Palette); i++ {
- s.palette[i] = color.NRGBAModel.Convert(img.Palette[i]).(color.NRGBA)
- }
- }
- return s
-}
-
-// scan scans the given rectangular region of the image into dst.
-func (s *scanner) scan(x1, y1, x2, y2 int, dst []uint8) {
- switch img := s.image.(type) {
- case *image.NRGBA:
- size := (x2 - x1) * 4
- j := 0
- i := y1*img.Stride + x1*4
- for y := y1; y < y2; y++ {
- copy(dst[j:j+size], img.Pix[i:i+size])
- j += size
- i += img.Stride
- }
-
- case *image.NRGBA64:
- j := 0
- for y := y1; y < y2; y++ {
- i := y*img.Stride + x1*8
- for x := x1; x < x2; x++ {
- dst[j+0] = img.Pix[i+0]
- dst[j+1] = img.Pix[i+2]
- dst[j+2] = img.Pix[i+4]
- dst[j+3] = img.Pix[i+6]
- j += 4
- i += 8
- }
- }
-
- case *image.RGBA:
- j := 0
- for y := y1; y < y2; y++ {
- i := y*img.Stride + x1*4
- for x := x1; x < x2; x++ {
- a := img.Pix[i+3]
- switch a {
- case 0:
- dst[j+0] = 0
- dst[j+1] = 0
- dst[j+2] = 0
- case 0xff:
- dst[j+0] = img.Pix[i+0]
- dst[j+1] = img.Pix[i+1]
- dst[j+2] = img.Pix[i+2]
- default:
- r16 := uint16(img.Pix[i+0])
- g16 := uint16(img.Pix[i+1])
- b16 := uint16(img.Pix[i+2])
- a16 := uint16(a)
- dst[j+0] = uint8(r16 * 0xff / a16)
- dst[j+1] = uint8(g16 * 0xff / a16)
- dst[j+2] = uint8(b16 * 0xff / a16)
- }
- dst[j+3] = a
- j += 4
- i += 4
- }
- }
-
- case *image.RGBA64:
- j := 0
- for y := y1; y < y2; y++ {
- i := y*img.Stride + x1*8
- for x := x1; x < x2; x++ {
- a := img.Pix[i+6]
- switch a {
- case 0:
- dst[j+0] = 0
- dst[j+1] = 0
- dst[j+2] = 0
- case 0xff:
- dst[j+0] = img.Pix[i+0]
- dst[j+1] = img.Pix[i+2]
- dst[j+2] = img.Pix[i+4]
- default:
- r32 := uint32(img.Pix[i+0])<<8 | uint32(img.Pix[i+1])
- g32 := uint32(img.Pix[i+2])<<8 | uint32(img.Pix[i+3])
- b32 := uint32(img.Pix[i+4])<<8 | uint32(img.Pix[i+5])
- a32 := uint32(img.Pix[i+6])<<8 | uint32(img.Pix[i+7])
- dst[j+0] = uint8((r32 * 0xffff / a32) >> 8)
- dst[j+1] = uint8((g32 * 0xffff / a32) >> 8)
- dst[j+2] = uint8((b32 * 0xffff / a32) >> 8)
- }
- dst[j+3] = a
- j += 4
- i += 8
- }
- }
-
- case *image.Gray:
- j := 0
- for y := y1; y < y2; y++ {
- i := y*img.Stride + x1
- for x := x1; x < x2; x++ {
- c := img.Pix[i]
- dst[j+0] = c
- dst[j+1] = c
- dst[j+2] = c
- dst[j+3] = 0xff
- j += 4
- i++
- }
- }
-
- case *image.Gray16:
- j := 0
- for y := y1; y < y2; y++ {
- i := y*img.Stride + x1*2
- for x := x1; x < x2; x++ {
- c := img.Pix[i]
- dst[j+0] = c
- dst[j+1] = c
- dst[j+2] = c
- dst[j+3] = 0xff
- j += 4
- i += 2
- }
- }
-
- case *image.YCbCr:
- j := 0
- x1 += img.Rect.Min.X
- x2 += img.Rect.Min.X
- y1 += img.Rect.Min.Y
- y2 += img.Rect.Min.Y
- for y := y1; y < y2; y++ {
- iy := (y-img.Rect.Min.Y)*img.YStride + (x1 - img.Rect.Min.X)
- for x := x1; x < x2; x++ {
- var ic int
- switch img.SubsampleRatio {
- case image.YCbCrSubsampleRatio444:
- ic = (y-img.Rect.Min.Y)*img.CStride + (x - img.Rect.Min.X)
- case image.YCbCrSubsampleRatio422:
- ic = (y-img.Rect.Min.Y)*img.CStride + (x/2 - img.Rect.Min.X/2)
- case image.YCbCrSubsampleRatio420:
- ic = (y/2-img.Rect.Min.Y/2)*img.CStride + (x/2 - img.Rect.Min.X/2)
- case image.YCbCrSubsampleRatio440:
- ic = (y/2-img.Rect.Min.Y/2)*img.CStride + (x - img.Rect.Min.X)
- default:
- ic = img.COffset(x, y)
- }
-
- yy := int(img.Y[iy])
- cb := int(img.Cb[ic]) - 128
- cr := int(img.Cr[ic]) - 128
-
- r := (yy<<16 + 91881*cr + 1<<15) >> 16
- if r > 0xff {
- r = 0xff
- } else if r < 0 {
- r = 0
- }
-
- g := (yy<<16 - 22554*cb - 46802*cr + 1<<15) >> 16
- if g > 0xff {
- g = 0xff
- } else if g < 0 {
- g = 0
- }
-
- b := (yy<<16 + 116130*cb + 1<<15) >> 16
- if b > 0xff {
- b = 0xff
- } else if b < 0 {
- b = 0
- }
-
- dst[j+0] = uint8(r)
- dst[j+1] = uint8(g)
- dst[j+2] = uint8(b)
- dst[j+3] = 0xff
-
- iy++
- j += 4
- }
- }
-
- case *image.Paletted:
- j := 0
- for y := y1; y < y2; y++ {
- i := y*img.Stride + x1
- for x := x1; x < x2; x++ {
- c := s.palette[img.Pix[i]]
- dst[j+0] = c.R
- dst[j+1] = c.G
- dst[j+2] = c.B
- dst[j+3] = c.A
- j += 4
- i++
- }
- }
-
- default:
- j := 0
- b := s.image.Bounds()
- x1 += b.Min.X
- x2 += b.Min.X
- y1 += b.Min.Y
- y2 += b.Min.Y
- for y := y1; y < y2; y++ {
- for x := x1; x < x2; x++ {
- r16, g16, b16, a16 := s.image.At(x, y).RGBA()
- switch a16 {
- case 0xffff:
- dst[j+0] = uint8(r16 >> 8)
- dst[j+1] = uint8(g16 >> 8)
- dst[j+2] = uint8(b16 >> 8)
- dst[j+3] = 0xff
- case 0:
- dst[j+0] = 0
- dst[j+1] = 0
- dst[j+2] = 0
- dst[j+3] = 0
- default:
- dst[j+0] = uint8(((r16 * 0xffff) / a16) >> 8)
- dst[j+1] = uint8(((g16 * 0xffff) / a16) >> 8)
- dst[j+2] = uint8(((b16 * 0xffff) / a16) >> 8)
- dst[j+3] = uint8(a16 >> 8)
- }
- j += 4
- }
- }
- }
-}
diff --git a/vendor/github.com/disintegration/imaging/tools.go b/vendor/github.com/disintegration/imaging/tools.go
deleted file mode 100644
index 7887946..0000000
--- a/vendor/github.com/disintegration/imaging/tools.go
+++ /dev/null
@@ -1,247 +0,0 @@
-package imaging
-
-import (
- "bytes"
- "image"
- "image/color"
- "math"
-)
-
-// 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{}
- }
-
- c := color.NRGBAModel.Convert(fillColor).(color.NRGBA)
- if (c == color.NRGBA{0, 0, 0, 0}) {
- return image.NewNRGBA(image.Rect(0, 0, width, height))
- }
-
- return &image.NRGBA{
- Pix: bytes.Repeat([]byte{c.R, c.G, c.B, c.A}, width*height),
- Stride: 4 * width,
- Rect: image.Rect(0, 0, width, height),
- }
-}
-
-// Clone returns a copy of the given image.
-func Clone(img image.Image) *image.NRGBA {
- src := newScanner(img)
- dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
- size := src.w * 4
- parallel(0, src.h, func(ys <-chan int) {
- for y := range ys {
- i := y * dst.Stride
- src.scan(0, y, src.w, y+1, dst.Pix[i:i+size])
- }
- })
- return dst
-}
-
-// Anchor is the anchor point for image alignment.
-type Anchor int
-
-// Anchor point positions.
-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 {
- r := rect.Intersect(img.Bounds()).Sub(img.Bounds().Min)
- if r.Empty() {
- return &image.NRGBA{}
- }
- src := newScanner(img)
- dst := image.NewNRGBA(image.Rect(0, 0, r.Dx(), r.Dy()))
- rowSize := r.Dx() * 4
- parallel(r.Min.Y, r.Max.Y, func(ys <-chan int) {
- for y := range ys {
- i := (y - r.Min.Y) * dst.Stride
- src.scan(r.Min.X, y, r.Max.X, y+1, dst.Pix[i:i+rowSize])
- }
- })
- return dst
-}
-
-// 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 {
- dst := Clone(background)
- pos = pos.Sub(background.Bounds().Min)
- pasteRect := image.Rectangle{Min: pos, Max: pos.Add(img.Bounds().Size())}
- interRect := pasteRect.Intersect(dst.Bounds())
- if interRect.Empty() {
- return dst
- }
- src := newScanner(img)
- parallel(interRect.Min.Y, interRect.Max.Y, func(ys <-chan int) {
- for y := range ys {
- x1 := interRect.Min.X - pasteRect.Min.X
- x2 := interRect.Max.X - pasteRect.Min.X
- y1 := y - pasteRect.Min.Y
- y2 := y1 + 1
- i1 := y*dst.Stride + interRect.Min.X*4
- i2 := i1 + interRect.Dx()*4
- src.scan(x1, y1, x2, y2, dst.Pix[i1:i2])
- }
- })
- 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 spriteImage over backgroundImage at the given position (x=50, y=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) // Ensure 0.0 <= opacity <= 1.0.
- dst := Clone(background)
- pos = pos.Sub(background.Bounds().Min)
- pasteRect := image.Rectangle{Min: pos, Max: pos.Add(img.Bounds().Size())}
- interRect := pasteRect.Intersect(dst.Bounds())
- if interRect.Empty() {
- return dst
- }
- src := newScanner(img)
- parallel(interRect.Min.Y, interRect.Max.Y, func(ys <-chan int) {
- scanLine := make([]uint8, interRect.Dx()*4)
- for y := range ys {
- x1 := interRect.Min.X - pasteRect.Min.X
- x2 := interRect.Max.X - pasteRect.Min.X
- y1 := y - pasteRect.Min.Y
- y2 := y1 + 1
- src.scan(x1, y1, x2, y2, scanLine)
- i := y*dst.Stride + interRect.Min.X*4
- j := 0
- for x := interRect.Min.X; x < interRect.Max.X; x++ {
- r1 := float64(dst.Pix[i+0])
- g1 := float64(dst.Pix[i+1])
- b1 := float64(dst.Pix[i+2])
- a1 := float64(dst.Pix[i+3])
-
- r2 := float64(scanLine[j+0])
- g2 := float64(scanLine[j+1])
- b2 := float64(scanLine[j+2])
- a2 := float64(scanLine[j+3])
-
- coef2 := opacity * a2 / 255
- coef1 := (1 - coef2) * a1 / 255
- coefSum := coef1 + coef2
- coef1 /= coefSum
- coef2 /= coefSum
-
- dst.Pix[i+0] = uint8(r1*coef1 + r2*coef2)
- dst.Pix[i+1] = uint8(g1*coef1 + g2*coef2)
- dst.Pix[i+2] = uint8(b1*coef1 + b2*coef2)
- dst.Pix[i+3] = uint8(math.Min(a1+a2*opacity*(255-a1)/255, 255))
-
- i += 4
- j += 4
- }
- }
- })
- return dst
-}
-
-// OverlayCenter overlays the img image to the center of the background image 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.
-func OverlayCenter(background, img image.Image, opacity float64) *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 Overlay(background, img, image.Point{x0, y0}, opacity)
-}
diff --git a/vendor/github.com/disintegration/imaging/transform.go b/vendor/github.com/disintegration/imaging/transform.go
deleted file mode 100644
index d788d0d..0000000
--- a/vendor/github.com/disintegration/imaging/transform.go
+++ /dev/null
@@ -1,271 +0,0 @@
-package imaging
-
-import (
- "image"
- "image/color"
- "math"
-)
-
-// FlipH flips the image horizontally (from left to right) and returns the transformed image.
-func FlipH(img image.Image) *image.NRGBA {
- src := newScanner(img)
- dstW := src.w
- dstH := src.h
- rowSize := dstW * 4
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
- parallel(0, dstH, func(ys <-chan int) {
- for dstY := range ys {
- i := dstY * dst.Stride
- srcY := dstY
- src.scan(0, srcY, src.w, srcY+1, dst.Pix[i:i+rowSize])
- reverse(dst.Pix[i : i+rowSize])
- }
- })
- return dst
-}
-
-// FlipV flips the image vertically (from top to bottom) and returns the transformed image.
-func FlipV(img image.Image) *image.NRGBA {
- src := newScanner(img)
- dstW := src.w
- dstH := src.h
- rowSize := dstW * 4
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
- parallel(0, dstH, func(ys <-chan int) {
- for dstY := range ys {
- i := dstY * dst.Stride
- srcY := dstH - dstY - 1
- src.scan(0, srcY, src.w, srcY+1, dst.Pix[i:i+rowSize])
- }
- })
- return dst
-}
-
-// Transpose flips the image horizontally and rotates 90 degrees counter-clockwise.
-func Transpose(img image.Image) *image.NRGBA {
- src := newScanner(img)
- dstW := src.h
- dstH := src.w
- rowSize := dstW * 4
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
- parallel(0, dstH, func(ys <-chan int) {
- for dstY := range ys {
- i := dstY * dst.Stride
- srcX := dstY
- src.scan(srcX, 0, srcX+1, src.h, dst.Pix[i:i+rowSize])
- }
- })
- return dst
-}
-
-// Transverse flips the image vertically and rotates 90 degrees counter-clockwise.
-func Transverse(img image.Image) *image.NRGBA {
- src := newScanner(img)
- dstW := src.h
- dstH := src.w
- rowSize := dstW * 4
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
- parallel(0, dstH, func(ys <-chan int) {
- for dstY := range ys {
- i := dstY * dst.Stride
- srcX := dstH - dstY - 1
- src.scan(srcX, 0, srcX+1, src.h, dst.Pix[i:i+rowSize])
- reverse(dst.Pix[i : i+rowSize])
- }
- })
- return dst
-}
-
-// Rotate90 rotates the image 90 degrees counter-clockwise and returns the transformed image.
-func Rotate90(img image.Image) *image.NRGBA {
- src := newScanner(img)
- dstW := src.h
- dstH := src.w
- rowSize := dstW * 4
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
- parallel(0, dstH, func(ys <-chan int) {
- for dstY := range ys {
- i := dstY * dst.Stride
- srcX := dstH - dstY - 1
- src.scan(srcX, 0, srcX+1, src.h, dst.Pix[i:i+rowSize])
- }
- })
- return dst
-}
-
-// Rotate180 rotates the image 180 degrees counter-clockwise and returns the transformed image.
-func Rotate180(img image.Image) *image.NRGBA {
- src := newScanner(img)
- dstW := src.w
- dstH := src.h
- rowSize := dstW * 4
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
- parallel(0, dstH, func(ys <-chan int) {
- for dstY := range ys {
- i := dstY * dst.Stride
- srcY := dstH - dstY - 1
- src.scan(0, srcY, src.w, srcY+1, dst.Pix[i:i+rowSize])
- reverse(dst.Pix[i : i+rowSize])
- }
- })
- return dst
-}
-
-// Rotate270 rotates the image 270 degrees counter-clockwise and returns the transformed image.
-func Rotate270(img image.Image) *image.NRGBA {
- src := newScanner(img)
- dstW := src.h
- dstH := src.w
- rowSize := dstW * 4
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
- parallel(0, dstH, func(ys <-chan int) {
- for dstY := range ys {
- i := dstY * dst.Stride
- srcX := dstY
- src.scan(srcX, 0, srcX+1, src.h, dst.Pix[i:i+rowSize])
- reverse(dst.Pix[i : i+rowSize])
- }
- })
- return dst
-}
-
-// Rotate rotates an image by the given angle counter-clockwise .
-// The angle parameter is the rotation angle in degrees.
-// The bgColor parameter specifies the color of the uncovered zone after the rotation.
-func Rotate(img image.Image, angle float64, bgColor color.Color) *image.NRGBA {
- angle = angle - math.Floor(angle/360)*360
-
- switch angle {
- case 0:
- return Clone(img)
- case 90:
- return Rotate90(img)
- case 180:
- return Rotate180(img)
- case 270:
- return Rotate270(img)
- }
-
- src := toNRGBA(img)
- srcW := src.Bounds().Max.X
- srcH := src.Bounds().Max.Y
- dstW, dstH := rotatedSize(srcW, srcH, angle)
- dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
-
- if dstW <= 0 || dstH <= 0 {
- return dst
- }
-
- srcXOff := float64(srcW)/2 - 0.5
- srcYOff := float64(srcH)/2 - 0.5
- dstXOff := float64(dstW)/2 - 0.5
- dstYOff := float64(dstH)/2 - 0.5
-
- bgColorNRGBA := color.NRGBAModel.Convert(bgColor).(color.NRGBA)
- sin, cos := math.Sincos(math.Pi * angle / 180)
-
- parallel(0, dstH, func(ys <-chan int) {
- for dstY := range ys {
- for dstX := 0; dstX < dstW; dstX++ {
- xf, yf := rotatePoint(float64(dstX)-dstXOff, float64(dstY)-dstYOff, sin, cos)
- xf, yf = xf+srcXOff, yf+srcYOff
- interpolatePoint(dst, dstX, dstY, src, xf, yf, bgColorNRGBA)
- }
- }
- })
-
- return dst
-}
-
-func rotatePoint(x, y, sin, cos float64) (float64, float64) {
- return x*cos - y*sin, x*sin + y*cos
-}
-
-func rotatedSize(w, h int, angle float64) (int, int) {
- if w <= 0 || h <= 0 {
- return 0, 0
- }
-
- sin, cos := math.Sincos(math.Pi * angle / 180)
- x1, y1 := rotatePoint(float64(w-1), 0, sin, cos)
- x2, y2 := rotatePoint(float64(w-1), float64(h-1), sin, cos)
- x3, y3 := rotatePoint(0, float64(h-1), sin, cos)
-
- minx := math.Min(x1, math.Min(x2, math.Min(x3, 0)))
- maxx := math.Max(x1, math.Max(x2, math.Max(x3, 0)))
- miny := math.Min(y1, math.Min(y2, math.Min(y3, 0)))
- maxy := math.Max(y1, math.Max(y2, math.Max(y3, 0)))
-
- neww := maxx - minx + 1
- if neww-math.Floor(neww) > 0.1 {
- neww++
- }
- newh := maxy - miny + 1
- if newh-math.Floor(newh) > 0.1 {
- newh++
- }
-
- return int(neww), int(newh)
-}
-
-func interpolatePoint(dst *image.NRGBA, dstX, dstY int, src *image.NRGBA, xf, yf float64, bgColor color.NRGBA) {
- dstIndex := dstY*dst.Stride + dstX*4
-
- x0 := int(math.Floor(xf))
- y0 := int(math.Floor(yf))
- bounds := src.Bounds()
- if !image.Pt(x0, y0).In(image.Rect(bounds.Min.X-1, bounds.Min.Y-1, bounds.Max.X, bounds.Max.Y)) {
- dst.Pix[dstIndex+0] = bgColor.R
- dst.Pix[dstIndex+1] = bgColor.G
- dst.Pix[dstIndex+2] = bgColor.B
- dst.Pix[dstIndex+3] = bgColor.A
- return
- }
-
- xq := xf - float64(x0)
- yq := yf - float64(y0)
-
- var pxs [4]color.NRGBA
- var cfs [4]float64
-
- for i := 0; i < 2; i++ {
- for j := 0; j < 2; j++ {
- k := i*2 + j
- pt := image.Pt(x0+j, y0+i)
- if pt.In(bounds) {
- l := pt.Y*src.Stride + pt.X*4
- pxs[k].R = src.Pix[l+0]
- pxs[k].G = src.Pix[l+1]
- pxs[k].B = src.Pix[l+2]
- pxs[k].A = src.Pix[l+3]
- } else {
- pxs[k] = bgColor
- }
- }
- }
-
- cfs[0] = (1 - xq) * (1 - yq)
- cfs[1] = xq * (1 - yq)
- cfs[2] = (1 - xq) * yq
- cfs[3] = xq * yq
-
- var r, g, b, a float64
- for i := range pxs {
- wa := float64(pxs[i].A) * cfs[i]
- r += float64(pxs[i].R) * wa
- g += float64(pxs[i].G) * wa
- b += float64(pxs[i].B) * wa
- a += wa
- }
-
- if a != 0 {
- r /= a
- g /= a
- b /= a
- }
-
- dst.Pix[dstIndex+0] = clamp(r)
- dst.Pix[dstIndex+1] = clamp(g)
- dst.Pix[dstIndex+2] = clamp(b)
- dst.Pix[dstIndex+3] = clamp(a)
-}
diff --git a/vendor/github.com/disintegration/imaging/utils.go b/vendor/github.com/disintegration/imaging/utils.go
deleted file mode 100644
index 3b6ad2e..0000000
--- a/vendor/github.com/disintegration/imaging/utils.go
+++ /dev/null
@@ -1,83 +0,0 @@
-package imaging
-
-import (
- "image"
- "runtime"
- "sync"
-)
-
-// parallel processes the data in separate goroutines.
-func parallel(start, stop int, fn func(<-chan int)) {
- count := stop - start
- if count < 1 {
- return
- }
-
- procs := runtime.GOMAXPROCS(0)
- if procs > count {
- procs = count
- }
-
- c := make(chan int, count)
- for i := start; i < stop; i++ {
- c <- i
- }
- close(c)
-
- var wg sync.WaitGroup
- for i := 0; i < procs; i++ {
- wg.Add(1)
- go func() {
- defer wg.Done()
- fn(c)
- }()
- }
- wg.Wait()
-}
-
-// absint returns the absolute value of i.
-func absint(i int) int {
- if i < 0 {
- return -i
- }
- return i
-}
-
-// clamp rounds and clamps float64 value to fit into uint8.
-func clamp(x float64) uint8 {
- v := int64(x + 0.5)
- if v > 255 {
- return 255
- }
- if v > 0 {
- return uint8(v)
- }
- return 0
-}
-
-func reverse(pix []uint8) {
- if len(pix) <= 4 {
- return
- }
- i := 0
- j := len(pix) - 4
- for i < j {
- pix[i+0], pix[j+0] = pix[j+0], pix[i+0]
- pix[i+1], pix[j+1] = pix[j+1], pix[i+1]
- pix[i+2], pix[j+2] = pix[j+2], pix[i+2]
- pix[i+3], pix[j+3] = pix[j+3], pix[i+3]
- i += 4
- j -= 4
- }
-}
-
-func toNRGBA(img image.Image) *image.NRGBA {
- if img, ok := img.(*image.NRGBA); ok {
- return &image.NRGBA{
- Pix: img.Pix,
- Stride: img.Stride,
- Rect: img.Rect.Sub(img.Rect.Min),
- }
- }
- return Clone(img)
-}