summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/disintegration/imaging/clone.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/disintegration/imaging/clone.go')
-rw-r--r--vendor/github.com/disintegration/imaging/clone.go312
1 files changed, 312 insertions, 0 deletions
diff --git a/vendor/github.com/disintegration/imaging/clone.go b/vendor/github.com/disintegration/imaging/clone.go
new file mode 100644
index 000000000..a22e01913
--- /dev/null
+++ b/vendor/github.com/disintegration/imaging/clone.go
@@ -0,0 +1,312 @@
+package imaging
+
+import (
+ "image"
+ "image/color"
+)
+
+// Clone returns a copy of the given image.
+func Clone(img image.Image) *image.NRGBA {
+ dstBounds := img.Bounds().Sub(img.Bounds().Min)
+ dst := image.NewNRGBA(dstBounds)
+
+ switch src := img.(type) {
+ case *image.NRGBA:
+ copyNRGBA(dst, src)
+ case *image.NRGBA64:
+ copyNRGBA64(dst, src)
+ case *image.RGBA:
+ copyRGBA(dst, src)
+ case *image.RGBA64:
+ copyRGBA64(dst, src)
+ case *image.Gray:
+ copyGray(dst, src)
+ case *image.Gray16:
+ copyGray16(dst, src)
+ case *image.YCbCr:
+ copyYCbCr(dst, src)
+ case *image.Paletted:
+ copyPaletted(dst, src)
+ default:
+ copyImage(dst, src)
+ }
+
+ return dst
+}
+
+func copyNRGBA(dst *image.NRGBA, src *image.NRGBA) {
+ srcMinX := src.Rect.Min.X
+ srcMinY := src.Rect.Min.Y
+ dstW := dst.Rect.Dx()
+ dstH := dst.Rect.Dy()
+ rowSize := dstW * 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])
+ }
+ })
+}
+
+func copyNRGBA64(dst *image.NRGBA, src *image.NRGBA64) {
+ srcMinX := src.Rect.Min.X
+ srcMinY := src.Rect.Min.Y
+ dstW := dst.Rect.Dx()
+ dstH := dst.Rect.Dy()
+ 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
+ }
+ }
+ })
+}
+
+func copyRGBA(dst *image.NRGBA, src *image.RGBA) {
+ srcMinX := src.Rect.Min.X
+ srcMinY := src.Rect.Min.Y
+ dstW := dst.Rect.Dx()
+ dstH := dst.Rect.Dy()
+ 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
+ }
+ }
+ })
+}
+
+func copyRGBA64(dst *image.NRGBA, src *image.RGBA64) {
+ srcMinX := src.Rect.Min.X
+ srcMinY := src.Rect.Min.Y
+ dstW := dst.Rect.Dx()
+ dstH := dst.Rect.Dy()
+ 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
+ }
+ }
+ })
+}
+
+func copyGray(dst *image.NRGBA, src *image.Gray) {
+ srcMinX := src.Rect.Min.X
+ srcMinY := src.Rect.Min.Y
+ dstW := dst.Rect.Dx()
+ dstH := dst.Rect.Dy()
+ 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++
+ }
+ }
+ })
+}
+
+func copyGray16(dst *image.NRGBA, src *image.Gray16) {
+ srcMinX := src.Rect.Min.X
+ srcMinY := src.Rect.Min.Y
+ dstW := dst.Rect.Dx()
+ dstH := dst.Rect.Dy()
+ 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
+ }
+ }
+ })
+}
+
+func copyYCbCr(dst *image.NRGBA, src *image.YCbCr) {
+ srcMinX := src.Rect.Min.X
+ srcMinY := src.Rect.Min.Y
+ dstW := dst.Rect.Dx()
+ dstH := dst.Rect.Dy()
+ parallel(dstH, func(partStart, partEnd int) {
+ for dstY := partStart; dstY < partEnd; dstY++ {
+ srcY := srcMinY + dstY
+ di := dst.PixOffset(0, dstY)
+ for dstX := 0; dstX < dstW; dstX++ {
+ srcX := srcMinX + dstX
+
+ siy := (srcY-srcMinY)*src.YStride + (srcX - srcMinX)
+
+ var sic int
+ switch src.SubsampleRatio {
+ case image.YCbCrSubsampleRatio444:
+ sic = (srcY-srcMinY)*src.CStride + (srcX - srcMinX)
+ case image.YCbCrSubsampleRatio422:
+ sic = (srcY-srcMinY)*src.CStride + (srcX/2 - srcMinX/2)
+ case image.YCbCrSubsampleRatio420:
+ sic = (srcY/2-srcMinY/2)*src.CStride + (srcX/2 - srcMinX/2)
+ case image.YCbCrSubsampleRatio440:
+ sic = (srcY/2-srcMinY/2)*src.CStride + (srcX - srcMinX)
+ default:
+ sic = src.COffset(srcX, srcY)
+ }
+
+ y := int32(src.Y[siy])
+ cb := int32(src.Cb[sic]) - 128
+ cr := int32(src.Cr[sic]) - 128
+
+ r := (y<<16 + 91881*cr + 1<<15) >> 16
+ if r > 255 {
+ r = 255
+ } else if r < 0 {
+ r = 0
+ }
+
+ g := (y<<16 - 22554*cb - 46802*cr + 1<<15) >> 16
+ if g > 255 {
+ g = 255
+ } else if g < 0 {
+ g = 0
+ }
+
+ b := (y<<16 + 116130*cb + 1<<15) >> 16
+ if b > 255 {
+ b = 255
+ } else if b < 0 {
+ b = 0
+ }
+
+ dst.Pix[di+0] = uint8(r)
+ dst.Pix[di+1] = uint8(g)
+ dst.Pix[di+2] = uint8(b)
+ dst.Pix[di+3] = 255
+
+ di += 4
+ }
+ }
+ })
+}
+
+func copyPaletted(dst *image.NRGBA, src *image.Paletted) {
+ srcMinX := src.Rect.Min.X
+ srcMinY := src.Rect.Min.Y
+ dstW := dst.Rect.Dx()
+ dstH := dst.Rect.Dy()
+ 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++
+ }
+ }
+ })
+}
+
+func copyImage(dst *image.NRGBA, src image.Image) {
+ srcMinX := src.Bounds().Min.X
+ srcMinY := src.Bounds().Min.Y
+ dstW := dst.Bounds().Dx()
+ dstH := dst.Bounds().Dy()
+ 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(src.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
+ }
+ }
+ })
+}
+
+// toNRGBA converts any image type to *image.NRGBA with min-point at (0, 0).
+func toNRGBA(img image.Image) *image.NRGBA {
+ if img, ok := img.(*image.NRGBA); ok && img.Bounds().Min.Eq(image.ZP) {
+ return img
+ }
+ return Clone(img)
+}