diff options
34 files changed, 653 insertions, 7130 deletions
| @@ -29,7 +29,6 @@ require (  	github.com/KimMachineGun/automemlimit v0.6.1  	github.com/buckket/go-blurhash v1.1.0  	github.com/coreos/go-oidc/v3 v3.11.0 -	github.com/disintegration/imaging v1.6.2  	github.com/gin-contrib/cors v1.7.2  	github.com/gin-contrib/gzip v1.0.1  	github.com/gin-contrib/sessions v1.0.1 @@ -145,8 +145,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs  github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=  github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=  github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= -github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=  github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=  github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=  github.com/dsoprea/go-exif/v2 v2.0.0-20200321225314-640175a69fe4/go.mod h1:Lm2lMM2zx8p4a34ZemkaUV95AnMl4ZvLbCUbwOvLC2E= @@ -692,7 +690,6 @@ golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUF  golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=  golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=  golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=  golang.org/x/image v0.19.0 h1:D9FX4QWkLfkeqaC62SonffIIuYdOk/UE2XKUBgRIBIQ=  golang.org/x/image v0.19.0/go.mod h1:y0zrRqlQRWQ5PXaYCOMLTW2fpsxZ8Qh9I/ohnInJEys=  golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/internal/api/client/instance/instancepatch_test.go b/internal/api/client/instance/instancepatch_test.go index 6148ed93e..8b099984d 100644 --- a/internal/api/client/instance/instancepatch_test.go +++ b/internal/api/client/instance/instancepatch_test.go @@ -858,7 +858,7 @@ func (suite *InstancePatchTestSuite) TestInstancePatch8() {    "static_url": "http://localhost:8080/fileserver/01AY6P665V14JJR0AFVRT7311Y/attachment/small/`+instanceAccount.AvatarMediaAttachment.ID+`.webp",`+`    "thumbnail_static_type": "image/webp",    "thumbnail_description": "A bouncing little green peglin.", -  "blurhash": "LF9kG$RR4YtP%dR+V^t5D,oxx?WC" +  "blurhash": "LE9801Rl4Yt5%dWCV]t5Dmoex?WC"  }`, string(instanceV2ThumbnailJson))  	// double extra special bonus: now update the image description without changing the image diff --git a/internal/api/client/media/mediacreate_test.go b/internal/api/client/media/mediacreate_test.go index e7f98d6d7..2eec8341f 100644 --- a/internal/api/client/media/mediacreate_test.go +++ b/internal/api/client/media/mediacreate_test.go @@ -206,7 +206,7 @@ func (suite *MediaCreateTestSuite) TestMediaCreateSuccessful() {  			Y: 0.5,  		},  	}, *attachmentReply.Meta) -	suite.Equal("LiBzRk#6V[WF_NvzV@WY_3rqV@a$", *attachmentReply.Blurhash) +	suite.Equal("LiB|W-#6RQR.~qvzRjWF_3rqV@a$", *attachmentReply.Blurhash)  	suite.NotEmpty(attachmentReply.ID)  	suite.NotEmpty(attachmentReply.URL)  	suite.NotEmpty(attachmentReply.PreviewURL) @@ -291,7 +291,7 @@ func (suite *MediaCreateTestSuite) TestMediaCreateSuccessfulV2() {  			Y: 0.5,  		},  	}, *attachmentReply.Meta) -	suite.Equal("LiBzRk#6V[WF_NvzV@WY_3rqV@a$", *attachmentReply.Blurhash) +	suite.Equal("LiB|W-#6RQR.~qvzRjWF_3rqV@a$", *attachmentReply.Blurhash)  	suite.NotEmpty(attachmentReply.ID)  	suite.Nil(attachmentReply.URL)  	suite.NotEmpty(attachmentReply.PreviewURL) diff --git a/internal/media/imaging.go b/internal/media/imaging.go new file mode 100644 index 000000000..a9f73a066 --- /dev/null +++ b/internal/media/imaging.go @@ -0,0 +1,623 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. + +package media + +import ( +	"image" +	"image/color" +	"math" +) + +// NOTE: +// the following code is borrowed from +// github.com/disintegration/imaging +// and collapses in some places for our +// particular usecases and with parallel() +// function (spans work across goroutines) +// removed, instead working synchronously. +// +// at gotosocial we take particular +// care about where we spawn goroutines +// to ensure we're in control of the +// amount of concurrency in relation +// to the amount configured by user. + +// resizeDownLinear resizes image to given width x height using linear resampling. +// This is specifically optimized for resizing down (i.e. smaller), else is noop. +func resizeDownLinear(img image.Image, width, height int) image.Image { +	srcW, srcH := img.Bounds().Dx(), img.Bounds().Dy() +	if srcW <= 0 || srcH <= 0 || +		width < 0 || height < 0 { +		return &image.NRGBA{} +	} + +	if width == 0 { +		// If no width is given, use aspect preserving width. +		tmp := float64(height) * float64(srcW) / float64(srcH) +		width = int(math.Max(1.0, math.Floor(tmp+0.5))) +	} + +	if height == 0 { +		// If no height is given, use aspect preserving height. +		tmp := float64(width) * float64(srcH) / float64(srcW) +		height = int(math.Max(1.0, math.Floor(tmp+0.5))) +	} + +	if width < srcW { +		// Width is smaller, resize horizontally. +		img = resizeHorizontalLinear(img, width) +	} + +	if height < srcH { +		// Height is smaller, resize vertically. +		img = resizeVerticalLinear(img, height) +	} + +	return img +} + +// flipH flips the image horizontally (left to right). +func flipH(img image.Image) image.Image { +	src := newScanner(img) +	dstW := src.w +	dstH := src.h +	rowSize := dstW * 4 +	dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) +	for y := 0; y < dstH; y++ { +		i := y * dst.Stride +		srcY := y +		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). +func flipV(img image.Image) image.Image { +	src := newScanner(img) +	dstW := src.w +	dstH := src.h +	rowSize := dstW * 4 +	dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) +	for y := 0; y < dstH; y++ { +		i := y * dst.Stride +		srcY := dstH - y - 1 +		src.scan(0, srcY, src.w, srcY+1, dst.Pix[i:i+rowSize]) +	} +	return dst +} + +// rotate90 rotates the image 90 counter-clockwise. +func rotate90(img image.Image) image.Image { +	src := newScanner(img) +	dstW := src.h +	dstH := src.w +	rowSize := dstW * 4 +	dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) +	for y := 0; y < dstH; y++ { +		i := y * dst.Stride +		srcX := dstH - y - 1 +		src.scan(srcX, 0, srcX+1, src.h, dst.Pix[i:i+rowSize]) +	} +	return dst +} + +// rotate180 rotates the image 180 counter-clockwise. +func rotate180(img image.Image) image.Image { +	src := newScanner(img) +	dstW := src.w +	dstH := src.h +	rowSize := dstW * 4 +	dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) +	for y := 0; y < dstH; y++ { +		i := y * dst.Stride +		srcY := dstH - y - 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 counter-clockwise. +func rotate270(img image.Image) image.Image { +	src := newScanner(img) +	dstW := src.h +	dstH := src.w +	rowSize := dstW * 4 +	dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) +	for y := 0; y < dstH; y++ { +		i := y * dst.Stride +		srcX := y +		src.scan(srcX, 0, srcX+1, src.h, dst.Pix[i:i+rowSize]) +		reverse(dst.Pix[i : i+rowSize]) +	} +	return dst +} + +// transpose flips the image horizontally and rotates 90 counter-clockwise. +func transpose(img image.Image) image.Image { +	src := newScanner(img) +	dstW := src.h +	dstH := src.w +	rowSize := dstW * 4 +	dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) +	for y := 0; y < dstH; y++ { +		i := y * dst.Stride +		srcX := y +		src.scan(srcX, 0, srcX+1, src.h, dst.Pix[i:i+rowSize]) +	} +	return dst +} + +// transverse flips the image vertically and rotates 90 counter-clockwise. +func transverse(img image.Image) image.Image { +	src := newScanner(img) +	dstW := src.h +	dstH := src.w +	rowSize := dstW * 4 +	dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) +	for y := 0; y < dstH; y++ { +		i := y * dst.Stride +		srcX := dstH - y - 1 +		src.scan(srcX, 0, srcX+1, src.h, dst.Pix[i:i+rowSize]) +		reverse(dst.Pix[i : i+rowSize]) +	} +	return dst +} + +// resizeHorizontalLinear resizes image to given width using linear resampling. +func resizeHorizontalLinear(img image.Image, dstWidth int) image.Image { +	src := newScanner(img) +	dst := image.NewRGBA(image.Rect(0, 0, dstWidth, src.h)) +	weights := precomputeWeightsLinear(dstWidth, src.w) +	scanLine := make([]uint8, src.w*4) +	for y := 0; y < src.h; y++ { +		src.scan(0, y, src.w, y+1, scanLine) +		j0 := y * dst.Stride +		for x := range weights { +			var r, g, b, a float64 +			for _, w := range weights[x] { +				i := w.index * 4 +				s := scanLine[i : i+4 : i+4] +				aw := float64(s[3]) * w.weight +				r += float64(s[0]) * aw +				g += float64(s[1]) * aw +				b += float64(s[2]) * aw +				a += aw +			} +			if a != 0 { +				aInv := 1 / a +				j := j0 + x*4 +				d := dst.Pix[j : j+4 : j+4] +				d[0] = clampFloat(r * aInv) +				d[1] = clampFloat(g * aInv) +				d[2] = clampFloat(b * aInv) +				d[3] = clampFloat(a) +			} +		} +	} +	return dst +} + +// resizeVerticalLinear resizes image to given height using linear resampling. +func resizeVerticalLinear(img image.Image, height int) image.Image { +	src := newScanner(img) +	dst := image.NewNRGBA(image.Rect(0, 0, src.w, height)) +	weights := precomputeWeightsLinear(height, src.h) +	scanLine := make([]uint8, src.h*4) +	for x := 0; x < src.w; x++ { +		src.scan(x, 0, x+1, src.h, scanLine) +		for y := range weights { +			var r, g, b, a float64 +			for _, w := range weights[y] { +				i := w.index * 4 +				s := scanLine[i : i+4 : i+4] +				aw := float64(s[3]) * w.weight +				r += float64(s[0]) * aw +				g += float64(s[1]) * aw +				b += float64(s[2]) * aw +				a += aw +			} +			if a != 0 { +				aInv := 1 / a +				j := y*dst.Stride + x*4 +				d := dst.Pix[j : j+4 : j+4] +				d[0] = clampFloat(r * aInv) +				d[1] = clampFloat(g * aInv) +				d[2] = clampFloat(b * aInv) +				d[3] = clampFloat(a) +			} +		} +	} +	return dst +} + +type indexWeight struct { +	index  int +	weight float64 +} + +func precomputeWeightsLinear(dstSize, srcSize int) [][]indexWeight { +	du := float64(srcSize) / float64(dstSize) +	scale := du +	if scale < 1.0 { +		scale = 1.0 +	} + +	ru := math.Ceil(scale) +	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 := resampleLinear((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 +} + +// resampleLinear is the resample kernel func for linear filtering. +func resampleLinear(x float64) float64 { +	x = math.Abs(x) +	if x < 1.0 { +		return 1.0 - x +	} +	return 0 +} + +// scanner wraps an image.Image for +// easier size access and image type +// agnostic access to data at coords. +type scanner struct { +	image   image.Image +	w, h    int +	palette []color.NRGBA +} + +// newScanner wraps an image.Image in scanner{} type. +func newScanner(img image.Image) *scanner { +	b := img.Bounds() +	s := &scanner{ +		image: img, + +		w: b.Dx(), +		h: b.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 +		if size == 4 { +			for y := y1; y < y2; y++ { +				d := dst[j : j+4 : j+4] +				s := img.Pix[i : i+4 : i+4] +				d[0] = s[0] +				d[1] = s[1] +				d[2] = s[2] +				d[3] = s[3] +				j += size +				i += img.Stride +			} +		} else { +			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++ { +				s := img.Pix[i : i+8 : i+8] +				d := dst[j : j+4 : j+4] +				d[0] = s[0] +				d[1] = s[2] +				d[2] = s[4] +				d[3] = s[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++ { +				d := dst[j : j+4 : j+4] +				a := img.Pix[i+3] +				switch a { +				case 0: +					d[0] = 0 +					d[1] = 0 +					d[2] = 0 +					d[3] = a +				case 0xff: +					s := img.Pix[i : i+4 : i+4] +					d[0] = s[0] +					d[1] = s[1] +					d[2] = s[2] +					d[3] = a +				default: +					s := img.Pix[i : i+4 : i+4] +					r16 := uint16(s[0]) +					g16 := uint16(s[1]) +					b16 := uint16(s[2]) +					a16 := uint16(a) +					d[0] = uint8(r16 * 0xff / a16) +					d[1] = uint8(g16 * 0xff / a16) +					d[2] = uint8(b16 * 0xff / a16) +					d[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++ { +				s := img.Pix[i : i+8 : i+8] +				d := dst[j : j+4 : j+4] +				a := s[6] +				switch a { +				case 0: +					d[0] = 0 +					d[1] = 0 +					d[2] = 0 +				case 0xff: +					d[0] = s[0] +					d[1] = s[2] +					d[2] = s[4] +				default: +					r32 := uint32(s[0])<<8 | uint32(s[1]) +					g32 := uint32(s[2])<<8 | uint32(s[3]) +					b32 := uint32(s[4])<<8 | uint32(s[5]) +					a32 := uint32(s[6])<<8 | uint32(s[7]) +					d[0] = uint8((r32 * 0xffff / a32) >> 8) +					d[1] = uint8((g32 * 0xffff / a32) >> 8) +					d[2] = uint8((b32 * 0xffff / a32) >> 8) +				} +				d[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] +				d := dst[j : j+4 : j+4] +				d[0] = c +				d[1] = c +				d[2] = c +				d[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] +				d := dst[j : j+4 : j+4] +				d[0] = c +				d[1] = c +				d[2] = c +				d[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 + +		hy := img.Rect.Min.Y / 2 +		hx := img.Rect.Min.X / 2 +		for y := y1; y < y2; y++ { +			iy := (y-img.Rect.Min.Y)*img.YStride + (x1 - img.Rect.Min.X) + +			var yBase int +			switch img.SubsampleRatio { +			case image.YCbCrSubsampleRatio444, image.YCbCrSubsampleRatio422: +				yBase = (y - img.Rect.Min.Y) * img.CStride +			case image.YCbCrSubsampleRatio420, image.YCbCrSubsampleRatio440: +				yBase = (y/2 - hy) * img.CStride +			} + +			for x := x1; x < x2; x++ { +				var ic int +				switch img.SubsampleRatio { +				case image.YCbCrSubsampleRatio444, image.YCbCrSubsampleRatio440: +					ic = yBase + (x - img.Rect.Min.X) +				case image.YCbCrSubsampleRatio422, image.YCbCrSubsampleRatio420: +					ic = yBase + (x/2 - hx) +				default: +					ic = img.COffset(x, y) +				} + +				yy1 := int32(img.Y[iy]) * 0x10101 +				cb1 := int32(img.Cb[ic]) - 128 +				cr1 := int32(img.Cr[ic]) - 128 + +				r := yy1 + 91881*cr1 +				if uint32(r)&0xff000000 == 0 { +					r >>= 16 +				} else { +					r = ^(r >> 31) +				} + +				g := yy1 - 22554*cb1 - 46802*cr1 +				if uint32(g)&0xff000000 == 0 { +					g >>= 16 +				} else { +					g = ^(g >> 31) +				} + +				b := yy1 + 116130*cb1 +				if uint32(b)&0xff000000 == 0 { +					b >>= 16 +				} else { +					b = ^(b >> 31) +				} + +				d := dst[j : j+4 : j+4] +				d[0] = uint8(r) +				d[1] = uint8(g) +				d[2] = uint8(b) +				d[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]] +				d := dst[j : j+4 : j+4] +				d[0] = c.R +				d[1] = c.G +				d[2] = c.B +				d[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() +				d := dst[j : j+4 : j+4] +				switch a16 { +				case 0xffff: +					d[0] = uint8(r16 >> 8) +					d[1] = uint8(g16 >> 8) +					d[2] = uint8(b16 >> 8) +					d[3] = 0xff +				case 0: +					d[0] = 0 +					d[1] = 0 +					d[2] = 0 +					d[3] = 0 +				default: +					d[0] = uint8(((r16 * 0xffff) / a16) >> 8) +					d[1] = uint8(((g16 * 0xffff) / a16) >> 8) +					d[2] = uint8(((b16 * 0xffff) / a16) >> 8) +					d[3] = uint8(a16 >> 8) +				} +				j += 4 +			} +		} +	} +} + +// reverse reverses the data +// in contained pixel slice. +func reverse(pix []uint8) { +	if len(pix) <= 4 { +		return +	} +	i := 0 +	j := len(pix) - 4 +	for i < j { +		pi := pix[i : i+4 : i+4] +		pj := pix[j : j+4 : j+4] +		pi[0], pj[0] = pj[0], pi[0] +		pi[1], pj[1] = pj[1], pi[1] +		pi[2], pj[2] = pj[2], pi[2] +		pi[3], pj[3] = pj[3], pi[3] +		i += 4 +		j -= 4 +	} +} + +// clampFloat rounds and clamps float64 value to fit into uint8. +func clampFloat(x float64) uint8 { +	v := int64(x + 0.5) +	if v > 255 { +		return 255 +	} +	if v > 0 { +		return uint8(v) +	} +	return 0 +} diff --git a/internal/media/manager_test.go b/internal/media/manager_test.go index ff38176f1..29ed95ffa 100644 --- a/internal/media/manager_test.go +++ b/internal/media/manager_test.go @@ -276,7 +276,7 @@ func (suite *ManagerTestSuite) TestSimpleJpegProcess() {  	suite.Equal("image/jpeg", attachment.Thumbnail.ContentType)  	suite.Equal(269739, attachment.File.FileSize)  	suite.Equal(22858, attachment.Thumbnail.FileSize) -	suite.Equal("LiBzRk#6V[WF_NvzV@WY_3rqV@a$", attachment.Blurhash) +	suite.Equal("LiB|W-#6RQR.~qvzRjWF_3rqV@a$", attachment.Blurhash)  	// now make sure the attachment is in the database  	dbAttachment, err := suite.db.GetAttachmentByID(ctx, attachment.ID) @@ -429,7 +429,7 @@ func (suite *ManagerTestSuite) TestSlothVineProcess() {  	suite.Equal("image/webp", attachment.Thumbnail.ContentType)  	suite.Equal(312453, attachment.File.FileSize)  	suite.Equal(5648, attachment.Thumbnail.FileSize) -	suite.Equal("LfIYH~xtNskCxtfPW.kB_4aespof", attachment.Blurhash) +	suite.Equal("LgIYH}xtNsofxtfPW.j[_4axn+of", attachment.Blurhash)  	// now make sure the attachment is in the database  	dbAttachment, err := suite.db.GetAttachmentByID(ctx, attachment.ID) @@ -489,7 +489,7 @@ func (suite *ManagerTestSuite) TestLongerMp4Process() {  	suite.Equal("image/webp", attachment.Thumbnail.ContentType)  	suite.Equal(109569, attachment.File.FileSize)  	suite.Equal(2976, attachment.Thumbnail.FileSize) -	suite.Equal("LJQJfm?bM{?b~qRjt7WBayWBofWB", attachment.Blurhash) +	suite.Equal("LIQJfl_3IU?b~qM{ofayWBWVofRj", attachment.Blurhash)  	// now make sure the attachment is in the database  	dbAttachment, err := suite.db.GetAttachmentByID(ctx, attachment.ID) @@ -549,7 +549,7 @@ func (suite *ManagerTestSuite) TestBirdnestMp4Process() {  	suite.Equal("image/webp", attachment.Thumbnail.ContentType)  	suite.Equal(1409625, attachment.File.FileSize)  	suite.Equal(14478, attachment.Thumbnail.FileSize) -	suite.Equal("LJF?FZV@RO.99DM_RPWAx]V?ayMw", attachment.Blurhash) +	suite.Equal("LLF$qyaeRO.9DgM_RPaetkV@WCMw", attachment.Blurhash)  	// now make sure the attachment is in the database  	dbAttachment, err := suite.db.GetAttachmentByID(ctx, attachment.ID) @@ -657,7 +657,7 @@ func (suite *ManagerTestSuite) TestPngNoAlphaChannelProcess() {  	suite.Equal("image/jpeg", attachment.Thumbnail.ContentType)  	suite.Equal(17471, attachment.File.FileSize)  	suite.Equal(6446, attachment.Thumbnail.FileSize) -	suite.Equal("LFQT7e.A%O%4?co$M}M{_1W9~TxV", attachment.Blurhash) +	suite.Equal("LGP%YL.A-?tA.9o#RURQ~ojp^~xW", attachment.Blurhash)  	// now make sure the attachment is in the database  	dbAttachment, err := suite.db.GetAttachmentByID(ctx, attachment.ID) @@ -713,7 +713,7 @@ func (suite *ManagerTestSuite) TestPngAlphaChannelProcess() {  	suite.Equal("image/webp", attachment.Thumbnail.ContentType)  	suite.Equal(18832, attachment.File.FileSize)  	suite.Equal(3592, attachment.Thumbnail.FileSize) -	suite.Equal("LCONII.A%Oxw?co#M}M{_1ac~TxV", attachment.Blurhash) +	suite.Equal("LCN^lE.A-?xd?co#N1RQ~ojp~SxW", attachment.Blurhash)  	// now make sure the attachment is in the database  	dbAttachment, err := suite.db.GetAttachmentByID(ctx, attachment.ID) @@ -769,7 +769,7 @@ func (suite *ManagerTestSuite) TestSimpleJpegProcessWithCallback() {  	suite.Equal("image/jpeg", attachment.Thumbnail.ContentType)  	suite.Equal(269739, attachment.File.FileSize)  	suite.Equal(22858, attachment.Thumbnail.FileSize) -	suite.Equal("LiBzRk#6V[WF_NvzV@WY_3rqV@a$", attachment.Blurhash) +	suite.Equal("LiB|W-#6RQR.~qvzRjWF_3rqV@a$", attachment.Blurhash)  	// now make sure the attachment is in the database  	dbAttachment, err := suite.db.GetAttachmentByID(ctx, attachment.ID) @@ -847,7 +847,7 @@ func (suite *ManagerTestSuite) TestSimpleJpegProcessWithDiskStorage() {  	suite.Equal("image/jpeg", attachment.Thumbnail.ContentType)  	suite.Equal(269739, attachment.File.FileSize)  	suite.Equal(22858, attachment.Thumbnail.FileSize) -	suite.Equal("LiBzRk#6V[WF_NvzV@WY_3rqV@a$", attachment.Blurhash) +	suite.Equal("LiB|W-#6RQR.~qvzRjWF_3rqV@a$", attachment.Blurhash)  	// now make sure the attachment is in the database  	dbAttachment, err := suite.db.GetAttachmentByID(ctx, attachment.ID) diff --git a/internal/media/thumbnail.go b/internal/media/thumbnail.go index a562dc2ad..322af8d7e 100644 --- a/internal/media/thumbnail.go +++ b/internal/media/thumbnail.go @@ -28,7 +28,6 @@ import (  	"strings"  	"github.com/buckket/go-blurhash" -	"github.com/disintegration/imaging"  	"github.com/superseriousbusiness/gotosocial/internal/gtserror"  	"github.com/superseriousbusiness/gotosocial/internal/log"  	"golang.org/x/image/webp" @@ -248,32 +247,25 @@ func generateNativeThumb(  	// taking orientation into account.  	switch orientation {  	case orientationFlipH: -		img = imaging.FlipH(img) +		img = flipH(img)  	case orientationFlipV: -		img = imaging.FlipV(img) +		img = flipV(img)  	case orientationRotate90: -		img = imaging.Rotate90(img) +		img = rotate90(img)  	case orientationRotate180: -		img = imaging.Rotate180(img) +		img = rotate180(img)  	case orientationRotate270: -		img = imaging.Rotate270(img) +		img = rotate270(img)  	case orientationTranspose: -		img = imaging.Transpose(img) +		img = transpose(img)  	case orientationTransverse: -		img = imaging.Transverse(img) +		img = transverse(img)  	} -	// Resize image to dimens only if necessary. -	if img.Bounds().Dx() > maxThumbWidth || -		img.Bounds().Dy() > maxThumbHeight { -		// Note: We could call "imaging.Fit" here -		// but there's no point, as we've already -		// calculated target dimensions beforehand. -		img = imaging.Resize(img, -			width, height, -			imaging.Linear, -		) -	} +	// Resize image to dimens. +	img = resizeDownLinear(img, +		width, height, +	)  	// Open output file at given path.  	outfile, err := os.Create(outpath) @@ -293,9 +285,10 @@ func generateNativeThumb(  	}  	if needBlurhash { -		// for generating blurhashes, it's more cost effective to -		// lose detail since it's blurry, so make a tiny version. -		tiny := imaging.Resize(img, 32, 0, imaging.NearestNeighbor) +		// for generating blurhashes, it's more +		// cost effective to lose detail since +		// it's blurry, so make a tiny version. +		tiny := resizeDownLinear(img, 32, 0)  		// Drop the larger image  		// ref as soon as possible @@ -332,9 +325,10 @@ func generateWebpBlurhash(filepath string) (string, error) {  		return "", gtserror.Newf("error decoding file %s: %w", filepath, err)  	} -	// for generating blurhashes, it's more cost effective to -	// lose detail since it's blurry, so make a tiny version. -	tiny := imaging.Resize(img, 32, 0, imaging.NearestNeighbor) +	// for generating blurhashes, it's more +	// cost effective to lose detail since +	// it's blurry, so make a tiny version. +	tiny := resizeDownLinear(img, 32, 0)  	// Drop the larger image  	// ref as soon as possible diff --git a/vendor/github.com/disintegration/imaging/.travis.yml b/vendor/github.com/disintegration/imaging/.travis.yml deleted file mode 100644 index 7ae5e4b25..000000000 --- a/vendor/github.com/disintegration/imaging/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: go -go: -  - "1.10.x" -  - "1.11.x" -  - "1.12.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 a4144a9d2..000000000 --- a/vendor/github.com/disintegration/imaging/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2012 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. diff --git a/vendor/github.com/disintegration/imaging/README.md b/vendor/github.com/disintegration/imaging/README.md deleted file mode 100644 index a1fd764d2..000000000 --- a/vendor/github.com/disintegration/imaging/README.md +++ /dev/null @@ -1,226 +0,0 @@ -# Imaging
 -
 -[](https://godoc.org/github.com/disintegration/imaging)
 -[](https://travis-ci.org/disintegration/imaging)
 -[](https://coveralls.io/github/disintegration/imaging?branch=master)
 -[](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, non-premultiplied 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:
 -- `Lanczos` - A high-quality resampling filter for photographic images yielding sharp results.
 -- `CatmullRom` - A sharp cubic filter that is faster than Lanczos filter while providing similar results.
 -- `MitchellNetravali` - A cubic filter that produces smoother results with less ringing artifacts than CatmullRom.
 -- `Linear` - Bilinear resampling filter, produces smooth output. 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.
 -
 -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:
 -
 -
 -
 -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` | 
 -`imaging.Linear`          | 
 -`imaging.CatmullRom`      | 
 -`imaging.Lanczos`         | 
 -
 -
 -### 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
 ------------------------------------|----------------------------------------|---------------------------------------
 - |  | 
 -
 -### 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
 ------------------------------------|-------------------------------------------|------------------------------------------
 - |  | 
 -
 -### Gamma correction
 -
 -```go
 -dstImage := imaging.AdjustGamma(srcImage, 0.75)
 -```
 -
 -Original image                     | Gamma = 0.75                             | Gamma = 1.25
 ------------------------------------|------------------------------------------|-----------------------------------------
 - |  | 
 -
 -### Contrast adjustment
 -
 -```go
 -dstImage := imaging.AdjustContrast(srcImage, 20)
 -```
 -
 -Original image                     | Contrast = 15                              | Contrast = -15
 ------------------------------------|--------------------------------------------|-------------------------------------------
 - |  | 
 -
 -### Brightness adjustment
 -
 -```go
 -dstImage := imaging.AdjustBrightness(srcImage, 20)
 -```
 -
 -Original image                     | Brightness = 10                              | Brightness = -10
 ------------------------------------|----------------------------------------------|---------------------------------------------
 - |  | 
 -
 -### Saturation adjustment
 -
 -```go
 -dstImage := imaging.AdjustSaturation(srcImage, 20)
 -```
 -
 -Original image                     | Saturation = 30                              | Saturation = -30
 ------------------------------------|----------------------------------------------|---------------------------------------------
 - |  | 
 -
 -## FAQ
 -
 -### Incorrect image orientation after processing (e.g. an image appears rotated after resizing)
 -
 -Most probably, the given image contains the EXIF orientation tag.
 -The stadard `image/*` packages do not support loading and saving
 -this kind of information. To fix the issue, try opening images with
 -the `AutoOrientation` decode option. If this option is set to `true`,
 -the image orientation is changed after decoding, according to the
 -orientation tag (if present). Here's the example:
 -
 -```go
 -img, err := imaging.Open("test.jpg", imaging.AutoOrientation(true))
 -```
 -
 -### What's the difference between `imaging` and `gift` packages?
 -
 -[imaging](https://github.com/disintegration/imaging)
 -is designed to be a lightweight and simple image manipulation package.
 -It provides basic image processing functions and a few helper functions
 -such as `Open` and `Save`. It consistently returns *image.NRGBA image 
 -type (8 bits per channel, RGBA).
 -
 -[gift](https://github.com/disintegration/gift)
 -supports more advanced image processing, for example, sRGB/Linear color
 -space conversions. It also supports different output image types
 -(e.g. 16 bits per channel) and provides easy-to-use API for chaining
 -multiple processing steps together.
 -
 -## 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:
 -
 -
 diff --git a/vendor/github.com/disintegration/imaging/adjust.go b/vendor/github.com/disintegration/imaging/adjust.go deleted file mode 100644 index daaf1de86..000000000 --- a/vendor/github.com/disintegration/imaging/adjust.go +++ /dev/null @@ -1,253 +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++ { -				d := dst.Pix[i : i+3 : i+3] -				r := d[0] -				g := d[1] -				b := d[2] -				f := 0.299*float64(r) + 0.587*float64(g) + 0.114*float64(b) -				y := uint8(f + 0.5) -				d[0] = y -				d[1] = y -				d[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++ { -				d := dst.Pix[i : i+3 : i+3] -				d[0] = 255 - d[0] -				d[1] = 255 - d[1] -				d[2] = 255 - d[2] -				i += 4 -			} -		} -	}) -	return dst -} - -// AdjustSaturation changes the saturation of the image using the percentage parameter and returns the adjusted image. -// The percentage must be in the range (-100, 100). -// The percentage = 0 gives the original image. -// The percentage = 100 gives the image with the saturation value doubled for each pixel. -// The percentage = -100 gives the image with the saturation value zeroed for each pixel (grayscale). -// -// Examples: -//  dstImage = imaging.AdjustSaturation(srcImage, 25) // Increase image saturation by 25%. -//  dstImage = imaging.AdjustSaturation(srcImage, -10) // Decrease image saturation by 10%. -// -func AdjustSaturation(img image.Image, percentage float64) *image.NRGBA { -	percentage = math.Min(math.Max(percentage, -100), 100) -	multiplier := 1 + percentage/100 - -	return AdjustFunc(img, func(c color.NRGBA) color.NRGBA { -		h, s, l := rgbToHSL(c.R, c.G, c.B) -		s *= multiplier -		if s > 1 { -			s = 1 -		} -		r, g, b := hslToRGB(h, s, l) -		return color.NRGBA{r, g, b, c.A} -	}) -} - -// 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++ { -		switch { -		case 0 <= v && v <= 1: -			lut[i] = clamp((0.5 + (float64(i)/255.0-0.5)*v) * 255.0) -		case 1 < v && v < 2: -			lut[i] = clamp((0.5 + (float64(i)/255.0-0.5)*(1/(2.0-v))) * 255.0) -		default: -			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)) -	lut = lut[0:256] -	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++ { -				d := dst.Pix[i : i+3 : i+3] -				d[0] = lut[d[0]] -				d[1] = lut[d[1]] -				d[2] = lut[d[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++ { -				d := dst.Pix[i : i+4 : i+4] -				r := d[0] -				g := d[1] -				b := d[2] -				a := d[3] -				c := fn(color.NRGBA{r, g, b, a}) -				d[0] = c.R -				d[1] = c.G -				d[2] = c.B -				d[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 11eddc162..000000000 --- a/vendor/github.com/disintegration/imaging/convolution.go +++ /dev/null @@ -1,148 +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 -					s := src.Pix[off : off+3 : off+3] -					r += float64(s[0]) * c.k -					g += float64(s[1]) * c.k -					b += float64(s[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 -				d := dst.Pix[dstOff : dstOff+4 : dstOff+4] -				d[0] = clamp(r) -				d[1] = clamp(g) -				d[2] = clamp(b) -				d[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 c98c91250..000000000 --- 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, non-premultiplied 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 47316b701..000000000 --- a/vendor/github.com/disintegration/imaging/effects.go +++ /dev/null @@ -1,169 +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. -// -// 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 := 0; x < src.w; x++ { -				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 -					s := scanLineF[i : i+4 : i+4] -					wa := s[3] * weight -					r += s[0] * wa -					g += s[1] * wa -					b += s[2] * wa -					a += wa -				} -				if a != 0 { -					aInv := 1 / a -					j := y*dst.Stride + x*4 -					d := dst.Pix[j : j+4 : j+4] -					d[0] = clamp(r * aInv) -					d[1] = clamp(g * aInv) -					d[2] = clamp(b * aInv) -					d[3] = clamp(a / wsum) -				} -			} -		} -	}) - -	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 -					s := scanLineF[i : i+4 : i+4] -					wa := s[3] * weight -					r += s[0] * wa -					g += s[1] * wa -					b += s[2] * wa -					a += wa -				} -				if a != 0 { -					aInv := 1 / a -					j := y*dst.Stride + x*4 -					d := dst.Pix[j : j+4 : j+4] -					d[0] = clamp(r * aInv) -					d[1] = clamp(g * aInv) -					d[2] = clamp(b * aInv) -					d[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. -// -// 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 c547fe822..000000000 --- a/vendor/github.com/disintegration/imaging/histogram.go +++ /dev/null @@ -1,52 +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++ { -				s := scanLine[i : i+3 : i+3] -				r := s[0] -				g := s[1] -				b := s[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 f6c6da86b..000000000 --- a/vendor/github.com/disintegration/imaging/io.go +++ /dev/null @@ -1,444 +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" -) - -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...) -} - -// Format is an image file format. -type Format int - -// Image file formats. -const ( -	JPEG Format = iota -	PNG -	GIF -	TIFF -	BMP -) - -var formatExts = map[string]Format{ -	"jpg":  JPEG, -	"jpeg": JPEG, -	"png":  PNG, -	"gif":  GIF, -	"tif":  TIFF, -	"tiff": TIFF, -	"bmp":  BMP, -} - -var formatNames = map[Format]string{ -	JPEG: "JPEG", -	PNG:  "PNG", -	GIF:  "GIF", -	TIFF: "TIFF", -	BMP:  "BMP", -} - -func (f Format) String() string { -	return formatNames[f] -} - -// ErrUnsupportedFormat means the given image format is not supported. -var ErrUnsupportedFormat = errors.New("imaging: unsupported image format") - -// FormatFromExtension parses image format from filename extension: -// "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported. -func FormatFromExtension(ext string) (Format, error) { -	if f, ok := formatExts[strings.ToLower(strings.TrimPrefix(ext, "."))]; ok { -		return f, nil -	} -	return -1, ErrUnsupportedFormat -} - -// FormatFromFilename parses image format from filename: -// "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) -} - -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) -	} - -	switch format { -	case JPEG: -		if nrgba, ok := img.(*image.NRGBA); ok && nrgba.Opaque() { -			rgba := &image.RGBA{ -				Pix:    nrgba.Pix, -				Stride: nrgba.Stride, -				Rect:   nrgba.Rect, -			} -			return jpeg.Encode(w, rgba, &jpeg.Options{Quality: cfg.jpegQuality}) -		} -		return jpeg.Encode(w, img, &jpeg.Options{Quality: cfg.jpegQuality}) - -	case PNG: -		encoder := png.Encoder{CompressionLevel: cfg.pngCompressionLevel} -		return encoder.Encode(w, img) - -	case GIF: -		return gif.Encode(w, img, &gif.Options{ -			NumColors: cfg.gifNumColors, -			Quantizer: cfg.gifQuantizer, -			Drawer:    cfg.gifDrawer, -		}) - -	case TIFF: -		return tiff.Encode(w, img, &tiff.Options{Compression: tiff.Deflate, Predictor: true}) - -	case BMP: -		return bmp.Encode(w, img) -	} - -	return ErrUnsupportedFormat -} - -// 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 -	} -	err = Encode(file, img, f, opts...) -	errc := file.Close() -	if err == nil { -		err = errc -	} -	return err -} - -// 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 706435e3d..000000000 --- a/vendor/github.com/disintegration/imaging/resize.go +++ /dev/null @@ -1,595 +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. -// -// 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 := range weights { -				var r, g, b, a float64 -				for _, w := range weights[x] { -					i := w.index * 4 -					s := scanLine[i : i+4 : i+4] -					aw := float64(s[3]) * w.weight -					r += float64(s[0]) * aw -					g += float64(s[1]) * aw -					b += float64(s[2]) * aw -					a += aw -				} -				if a != 0 { -					aInv := 1 / a -					j := j0 + x*4 -					d := dst.Pix[j : j+4 : j+4] -					d[0] = clamp(r * aInv) -					d[1] = clamp(g * aInv) -					d[2] = clamp(b * aInv) -					d[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 := range weights { -				var r, g, b, a float64 -				for _, w := range weights[y] { -					i := w.index * 4 -					s := scanLine[i : i+4 : i+4] -					aw := float64(s[3]) * w.weight -					r += float64(s[0]) * aw -					g += float64(s[1]) * aw -					b += float64(s[2]) * aw -					a += aw -				} -				if a != 0 { -					aInv := 1 / a -					j := y*dst.Stride + x*4 -					d := dst.Pix[j : j+4 : j+4] -					d[0] = clamp(r * aInv) -					d[1] = clamp(g * aInv) -					d[2] = clamp(b * aInv) -					d[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. -// -// 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 creates an image with the specified dimensions and fills it with the scaled source image. -// To achieve the correct aspect ratio without stretching, the source image will be cropped. -// -// 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 { -	dstW, dstH := width, height - -	if dstW <= 0 || dstH <= 0 { -		return &image.NRGBA{} -	} - -	srcBounds := img.Bounds() -	srcW := srcBounds.Dx() -	srcH := srcBounds.Dy() - -	if srcW <= 0 || srcH <= 0 { -		return &image.NRGBA{} -	} - -	if srcW == dstW && srcH == dstH { -		return Clone(img) -	} - -	if srcW >= 100 && srcH >= 100 { -		return cropAndResize(img, dstW, dstH, anchor, filter) -	} -	return resizeAndCrop(img, dstW, dstH, anchor, filter) -} - -// cropAndResize crops the image to the smallest possible size that has the required aspect ratio using -// the given anchor point, then scales it to the specified dimensions and returns the transformed image. -// -// This is generally faster than resizing first, but may result in inaccuracies when used on small source images. -func cropAndResize(img image.Image, width, height int, anchor Anchor, filter ResampleFilter) *image.NRGBA { -	dstW, dstH := width, height - -	srcBounds := img.Bounds() -	srcW := srcBounds.Dx() -	srcH := srcBounds.Dy() -	srcAspectRatio := float64(srcW) / float64(srcH) -	dstAspectRatio := float64(dstW) / float64(dstH) - -	var tmp *image.NRGBA -	if srcAspectRatio < dstAspectRatio { -		cropH := float64(srcW) * float64(dstH) / float64(dstW) -		tmp = CropAnchor(img, srcW, int(math.Max(1, cropH)+0.5), anchor) -	} else { -		cropW := float64(srcH) * float64(dstW) / float64(dstH) -		tmp = CropAnchor(img, int(math.Max(1, cropW)+0.5), srcH, anchor) -	} - -	return Resize(tmp, dstW, dstH, filter) -} - -// resizeAndCrop resizes 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. -func resizeAndCrop(img image.Image, width, height int, anchor Anchor, filter ResampleFilter) *image.NRGBA { -	dstW, dstH := width, height - -	srcBounds := img.Bounds() -	srcW := srcBounds.Dx() -	srcH := srcBounds.Dy() -	srcAspectRatio := float64(srcW) / float64(srcH) -	dstAspectRatio := float64(dstW) / float64(dstH) - -	var tmp *image.NRGBA -	if srcAspectRatio < dstAspectRatio { -		tmp = Resize(img, dstW, 0, filter) -	} else { -		tmp = Resize(img, 0, dstH, filter) -	} - -	return CropAnchor(tmp, dstW, dstH, 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. -// -// 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 specifies a resampling filter to be used for image resizing. -// -//	General filter recommendations: -// -//	- Lanczos -//		A high-quality resampling filter for photographic images yielding sharp results. -// -//	- CatmullRom -//		A sharp cubic filter that is faster than Lanczos filter while providing similar results. -// -//	- MitchellNetravali -//		A cubic filter that produces smoother results with less ringing artifacts than CatmullRom. -// -//	- Linear -//		Bilinear resampling filter, produces a smooth output. 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 37d92cef8..000000000 --- a/vendor/github.com/disintegration/imaging/scanner.go +++ /dev/null @@ -1,285 +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 -		if size == 4 { -			for y := y1; y < y2; y++ { -				d := dst[j : j+4 : j+4] -				s := img.Pix[i : i+4 : i+4] -				d[0] = s[0] -				d[1] = s[1] -				d[2] = s[2] -				d[3] = s[3] -				j += size -				i += img.Stride -			} -		} else { -			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++ { -				s := img.Pix[i : i+8 : i+8] -				d := dst[j : j+4 : j+4] -				d[0] = s[0] -				d[1] = s[2] -				d[2] = s[4] -				d[3] = s[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++ { -				d := dst[j : j+4 : j+4] -				a := img.Pix[i+3] -				switch a { -				case 0: -					d[0] = 0 -					d[1] = 0 -					d[2] = 0 -					d[3] = a -				case 0xff: -					s := img.Pix[i : i+4 : i+4] -					d[0] = s[0] -					d[1] = s[1] -					d[2] = s[2] -					d[3] = a -				default: -					s := img.Pix[i : i+4 : i+4] -					r16 := uint16(s[0]) -					g16 := uint16(s[1]) -					b16 := uint16(s[2]) -					a16 := uint16(a) -					d[0] = uint8(r16 * 0xff / a16) -					d[1] = uint8(g16 * 0xff / a16) -					d[2] = uint8(b16 * 0xff / a16) -					d[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++ { -				s := img.Pix[i : i+8 : i+8] -				d := dst[j : j+4 : j+4] -				a := s[6] -				switch a { -				case 0: -					d[0] = 0 -					d[1] = 0 -					d[2] = 0 -				case 0xff: -					d[0] = s[0] -					d[1] = s[2] -					d[2] = s[4] -				default: -					r32 := uint32(s[0])<<8 | uint32(s[1]) -					g32 := uint32(s[2])<<8 | uint32(s[3]) -					b32 := uint32(s[4])<<8 | uint32(s[5]) -					a32 := uint32(s[6])<<8 | uint32(s[7]) -					d[0] = uint8((r32 * 0xffff / a32) >> 8) -					d[1] = uint8((g32 * 0xffff / a32) >> 8) -					d[2] = uint8((b32 * 0xffff / a32) >> 8) -				} -				d[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] -				d := dst[j : j+4 : j+4] -				d[0] = c -				d[1] = c -				d[2] = c -				d[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] -				d := dst[j : j+4 : j+4] -				d[0] = c -				d[1] = c -				d[2] = c -				d[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 - -		hy := img.Rect.Min.Y / 2 -		hx := img.Rect.Min.X / 2 -		for y := y1; y < y2; y++ { -			iy := (y-img.Rect.Min.Y)*img.YStride + (x1 - img.Rect.Min.X) - -			var yBase int -			switch img.SubsampleRatio { -			case image.YCbCrSubsampleRatio444, image.YCbCrSubsampleRatio422: -				yBase = (y - img.Rect.Min.Y) * img.CStride -			case image.YCbCrSubsampleRatio420, image.YCbCrSubsampleRatio440: -				yBase = (y/2 - hy) * img.CStride -			} - -			for x := x1; x < x2; x++ { -				var ic int -				switch img.SubsampleRatio { -				case image.YCbCrSubsampleRatio444, image.YCbCrSubsampleRatio440: -					ic = yBase + (x - img.Rect.Min.X) -				case image.YCbCrSubsampleRatio422, image.YCbCrSubsampleRatio420: -					ic = yBase + (x/2 - hx) -				default: -					ic = img.COffset(x, y) -				} - -				yy1 := int32(img.Y[iy]) * 0x10101 -				cb1 := int32(img.Cb[ic]) - 128 -				cr1 := int32(img.Cr[ic]) - 128 - -				r := yy1 + 91881*cr1 -				if uint32(r)&0xff000000 == 0 { -					r >>= 16 -				} else { -					r = ^(r >> 31) -				} - -				g := yy1 - 22554*cb1 - 46802*cr1 -				if uint32(g)&0xff000000 == 0 { -					g >>= 16 -				} else { -					g = ^(g >> 31) -				} - -				b := yy1 + 116130*cb1 -				if uint32(b)&0xff000000 == 0 { -					b >>= 16 -				} else { -					b = ^(b >> 31) -				} - -				d := dst[j : j+4 : j+4] -				d[0] = uint8(r) -				d[1] = uint8(g) -				d[2] = uint8(b) -				d[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]] -				d := dst[j : j+4 : j+4] -				d[0] = c.R -				d[1] = c.G -				d[2] = c.B -				d[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() -				d := dst[j : j+4 : j+4] -				switch a16 { -				case 0xffff: -					d[0] = uint8(r16 >> 8) -					d[1] = uint8(g16 >> 8) -					d[2] = uint8(b16 >> 8) -					d[3] = 0xff -				case 0: -					d[0] = 0 -					d[1] = 0 -					d[2] = 0 -					d[3] = 0 -				default: -					d[0] = uint8(((r16 * 0xffff) / a16) >> 8) -					d[1] = uint8(((g16 * 0xffff) / a16) >> 8) -					d[2] = uint8(((b16 * 0xffff) / a16) >> 8) -					d[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 0ec19a039..000000000 --- a/vendor/github.com/disintegration/imaging/tools.go +++ /dev/null @@ -1,249 +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. -// -// 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++ { -				d := dst.Pix[i : i+4 : i+4] -				r1 := float64(d[0]) -				g1 := float64(d[1]) -				b1 := float64(d[2]) -				a1 := float64(d[3]) - -				s := scanLine[j : j+4 : j+4] -				r2 := float64(s[0]) -				g2 := float64(s[1]) -				b2 := float64(s[2]) -				a2 := float64(s[3]) - -				coef2 := opacity * a2 / 255 -				coef1 := (1 - coef2) * a1 / 255 -				coefSum := coef1 + coef2 -				coef1 /= coefSum -				coef2 /= coefSum - -				d[0] = uint8(r1*coef1 + r2*coef2) -				d[1] = uint8(g1*coef1 + g2*coef2) -				d[2] = uint8(b1*coef1 + b2*coef2) -				d[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 fe4a92f9d..000000000 --- a/vendor/github.com/disintegration/imaging/transform.go +++ /dev/null @@ -1,268 +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) { -	j := dstY*dst.Stride + dstX*4 -	d := dst.Pix[j : j+4 : j+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)) { -		d[0] = bgColor.R -		d[1] = bgColor.G -		d[2] = bgColor.B -		d[3] = bgColor.A -		return -	} - -	xq := xf - float64(x0) -	yq := yf - float64(y0) -	points := [4]image.Point{ -		{x0, y0}, -		{x0 + 1, y0}, -		{x0, y0 + 1}, -		{x0 + 1, y0 + 1}, -	} -	weights := [4]float64{ -		(1 - xq) * (1 - yq), -		xq * (1 - yq), -		(1 - xq) * yq, -		xq * yq, -	} - -	var r, g, b, a float64 -	for i := 0; i < 4; i++ { -		p := points[i] -		w := weights[i] -		if p.In(bounds) { -			i := p.Y*src.Stride + p.X*4 -			s := src.Pix[i : i+4 : i+4] -			wa := float64(s[3]) * w -			r += float64(s[0]) * wa -			g += float64(s[1]) * wa -			b += float64(s[2]) * wa -			a += wa -		} else { -			wa := float64(bgColor.A) * w -			r += float64(bgColor.R) * wa -			g += float64(bgColor.G) * wa -			b += float64(bgColor.B) * wa -			a += wa -		} -	} -	if a != 0 { -		aInv := 1 / a -		d[0] = clamp(r * aInv) -		d[1] = clamp(g * aInv) -		d[2] = clamp(b * aInv) -		d[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 6c7af1a51..000000000 --- a/vendor/github.com/disintegration/imaging/utils.go +++ /dev/null @@ -1,167 +0,0 @@ -package imaging - -import ( -	"image" -	"math" -	"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 { -		pi := pix[i : i+4 : i+4] -		pj := pix[j : j+4 : j+4] -		pi[0], pj[0] = pj[0], pi[0] -		pi[1], pj[1] = pj[1], pi[1] -		pi[2], pj[2] = pj[2], pi[2] -		pi[3], pj[3] = pj[3], pi[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) -} - -// rgbToHSL converts a color from RGB to HSL. -func rgbToHSL(r, g, b uint8) (float64, float64, float64) { -	rr := float64(r) / 255 -	gg := float64(g) / 255 -	bb := float64(b) / 255 - -	max := math.Max(rr, math.Max(gg, bb)) -	min := math.Min(rr, math.Min(gg, bb)) - -	l := (max + min) / 2 - -	if max == min { -		return 0, 0, l -	} - -	var h, s float64 -	d := max - min -	if l > 0.5 { -		s = d / (2 - max - min) -	} else { -		s = d / (max + min) -	} - -	switch max { -	case rr: -		h = (gg - bb) / d -		if g < b { -			h += 6 -		} -	case gg: -		h = (bb-rr)/d + 2 -	case bb: -		h = (rr-gg)/d + 4 -	} -	h /= 6 - -	return h, s, l -} - -// hslToRGB converts a color from HSL to RGB. -func hslToRGB(h, s, l float64) (uint8, uint8, uint8) { -	var r, g, b float64 -	if s == 0 { -		v := clamp(l * 255) -		return v, v, v -	} - -	var q float64 -	if l < 0.5 { -		q = l * (1 + s) -	} else { -		q = l + s - l*s -	} -	p := 2*l - q - -	r = hueToRGB(p, q, h+1/3.0) -	g = hueToRGB(p, q, h) -	b = hueToRGB(p, q, h-1/3.0) - -	return clamp(r * 255), clamp(g * 255), clamp(b * 255) -} - -func hueToRGB(p, q, t float64) float64 { -	if t < 0 { -		t++ -	} -	if t > 1 { -		t-- -	} -	if t < 1/6.0 { -		return p + (q-p)*6*t -	} -	if t < 1/2.0 { -		return q -	} -	if t < 2/3.0 { -		return p + (q-p)*(2/3.0-t)*6 -	} -	return p -} diff --git a/vendor/golang.org/x/image/bmp/reader.go b/vendor/golang.org/x/image/bmp/reader.go deleted file mode 100644 index 1939c1120..000000000 --- a/vendor/golang.org/x/image/bmp/reader.go +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package bmp implements a BMP image decoder and encoder. -// -// The BMP specification is at http://www.digicamsoft.com/bmp/bmp.html. -package bmp // import "golang.org/x/image/bmp" - -import ( -	"errors" -	"image" -	"image/color" -	"io" -) - -// ErrUnsupported means that the input BMP image uses a valid but unsupported -// feature. -var ErrUnsupported = errors.New("bmp: unsupported BMP image") - -func readUint16(b []byte) uint16 { -	return uint16(b[0]) | uint16(b[1])<<8 -} - -func readUint32(b []byte) uint32 { -	return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 -} - -// decodePaletted reads an 8 bit-per-pixel BMP image from r. -// If topDown is false, the image rows will be read bottom-up. -func decodePaletted(r io.Reader, c image.Config, topDown bool) (image.Image, error) { -	paletted := image.NewPaletted(image.Rect(0, 0, c.Width, c.Height), c.ColorModel.(color.Palette)) -	if c.Width == 0 || c.Height == 0 { -		return paletted, nil -	} -	var tmp [4]byte -	y0, y1, yDelta := c.Height-1, -1, -1 -	if topDown { -		y0, y1, yDelta = 0, c.Height, +1 -	} -	for y := y0; y != y1; y += yDelta { -		p := paletted.Pix[y*paletted.Stride : y*paletted.Stride+c.Width] -		if _, err := io.ReadFull(r, p); err != nil { -			return nil, err -		} -		// Each row is 4-byte aligned. -		if c.Width%4 != 0 { -			_, err := io.ReadFull(r, tmp[:4-c.Width%4]) -			if err != nil { -				return nil, err -			} -		} -	} -	return paletted, nil -} - -// decodeRGB reads a 24 bit-per-pixel BMP image from r. -// If topDown is false, the image rows will be read bottom-up. -func decodeRGB(r io.Reader, c image.Config, topDown bool) (image.Image, error) { -	rgba := image.NewRGBA(image.Rect(0, 0, c.Width, c.Height)) -	if c.Width == 0 || c.Height == 0 { -		return rgba, nil -	} -	// There are 3 bytes per pixel, and each row is 4-byte aligned. -	b := make([]byte, (3*c.Width+3)&^3) -	y0, y1, yDelta := c.Height-1, -1, -1 -	if topDown { -		y0, y1, yDelta = 0, c.Height, +1 -	} -	for y := y0; y != y1; y += yDelta { -		if _, err := io.ReadFull(r, b); err != nil { -			return nil, err -		} -		p := rgba.Pix[y*rgba.Stride : y*rgba.Stride+c.Width*4] -		for i, j := 0, 0; i < len(p); i, j = i+4, j+3 { -			// BMP images are stored in BGR order rather than RGB order. -			p[i+0] = b[j+2] -			p[i+1] = b[j+1] -			p[i+2] = b[j+0] -			p[i+3] = 0xFF -		} -	} -	return rgba, nil -} - -// decodeNRGBA reads a 32 bit-per-pixel BMP image from r. -// If topDown is false, the image rows will be read bottom-up. -func decodeNRGBA(r io.Reader, c image.Config, topDown, allowAlpha bool) (image.Image, error) { -	rgba := image.NewNRGBA(image.Rect(0, 0, c.Width, c.Height)) -	if c.Width == 0 || c.Height == 0 { -		return rgba, nil -	} -	y0, y1, yDelta := c.Height-1, -1, -1 -	if topDown { -		y0, y1, yDelta = 0, c.Height, +1 -	} -	for y := y0; y != y1; y += yDelta { -		p := rgba.Pix[y*rgba.Stride : y*rgba.Stride+c.Width*4] -		if _, err := io.ReadFull(r, p); err != nil { -			return nil, err -		} -		for i := 0; i < len(p); i += 4 { -			// BMP images are stored in BGRA order rather than RGBA order. -			p[i+0], p[i+2] = p[i+2], p[i+0] -			if !allowAlpha { -				p[i+3] = 0xFF -			} -		} -	} -	return rgba, nil -} - -// Decode reads a BMP image from r and returns it as an image.Image. -// Limitation: The file must be 8, 24 or 32 bits per pixel. -func Decode(r io.Reader) (image.Image, error) { -	c, bpp, topDown, allowAlpha, err := decodeConfig(r) -	if err != nil { -		return nil, err -	} -	switch bpp { -	case 8: -		return decodePaletted(r, c, topDown) -	case 24: -		return decodeRGB(r, c, topDown) -	case 32: -		return decodeNRGBA(r, c, topDown, allowAlpha) -	} -	panic("unreachable") -} - -// DecodeConfig returns the color model and dimensions of a BMP image without -// decoding the entire image. -// Limitation: The file must be 8, 24 or 32 bits per pixel. -func DecodeConfig(r io.Reader) (image.Config, error) { -	config, _, _, _, err := decodeConfig(r) -	return config, err -} - -func decodeConfig(r io.Reader) (config image.Config, bitsPerPixel int, topDown bool, allowAlpha bool, err error) { -	// We only support those BMP images with one of the following DIB headers: -	// - BITMAPINFOHEADER (40 bytes) -	// - BITMAPV4HEADER (108 bytes) -	// - BITMAPV5HEADER (124 bytes) -	const ( -		fileHeaderLen   = 14 -		infoHeaderLen   = 40 -		v4InfoHeaderLen = 108 -		v5InfoHeaderLen = 124 -	) -	var b [1024]byte -	if _, err := io.ReadFull(r, b[:fileHeaderLen+4]); err != nil { -		if err == io.EOF { -			err = io.ErrUnexpectedEOF -		} -		return image.Config{}, 0, false, false, err -	} -	if string(b[:2]) != "BM" { -		return image.Config{}, 0, false, false, errors.New("bmp: invalid format") -	} -	offset := readUint32(b[10:14]) -	infoLen := readUint32(b[14:18]) -	if infoLen != infoHeaderLen && infoLen != v4InfoHeaderLen && infoLen != v5InfoHeaderLen { -		return image.Config{}, 0, false, false, ErrUnsupported -	} -	if _, err := io.ReadFull(r, b[fileHeaderLen+4:fileHeaderLen+infoLen]); err != nil { -		if err == io.EOF { -			err = io.ErrUnexpectedEOF -		} -		return image.Config{}, 0, false, false, err -	} -	width := int(int32(readUint32(b[18:22]))) -	height := int(int32(readUint32(b[22:26]))) -	if height < 0 { -		height, topDown = -height, true -	} -	if width < 0 || height < 0 { -		return image.Config{}, 0, false, false, ErrUnsupported -	} -	// We only support 1 plane and 8, 24 or 32 bits per pixel and no -	// compression. -	planes, bpp, compression := readUint16(b[26:28]), readUint16(b[28:30]), readUint32(b[30:34]) -	// if compression is set to BI_BITFIELDS, but the bitmask is set to the default bitmask -	// that would be used if compression was set to 0, we can continue as if compression was 0 -	if compression == 3 && infoLen > infoHeaderLen && -		readUint32(b[54:58]) == 0xff0000 && readUint32(b[58:62]) == 0xff00 && -		readUint32(b[62:66]) == 0xff && readUint32(b[66:70]) == 0xff000000 { -		compression = 0 -	} -	if planes != 1 || compression != 0 { -		return image.Config{}, 0, false, false, ErrUnsupported -	} -	switch bpp { -	case 8: -		colorUsed := readUint32(b[46:50]) -		// If colorUsed is 0, it is set to the maximum number of colors for the given bpp, which is 2^bpp. -		if colorUsed == 0 { -			colorUsed = 256 -		} else if colorUsed > 256 { -			return image.Config{}, 0, false, false, ErrUnsupported -		} - -		if offset != fileHeaderLen+infoLen+colorUsed*4 { -			return image.Config{}, 0, false, false, ErrUnsupported -		} -		_, err = io.ReadFull(r, b[:colorUsed*4]) -		if err != nil { -			return image.Config{}, 0, false, false, err -		} -		pcm := make(color.Palette, colorUsed) -		for i := range pcm { -			// BMP images are stored in BGR order rather than RGB order. -			// Every 4th byte is padding. -			pcm[i] = color.RGBA{b[4*i+2], b[4*i+1], b[4*i+0], 0xFF} -		} -		return image.Config{ColorModel: pcm, Width: width, Height: height}, 8, topDown, false, nil -	case 24: -		if offset != fileHeaderLen+infoLen { -			return image.Config{}, 0, false, false, ErrUnsupported -		} -		return image.Config{ColorModel: color.RGBAModel, Width: width, Height: height}, 24, topDown, false, nil -	case 32: -		if offset != fileHeaderLen+infoLen { -			return image.Config{}, 0, false, false, ErrUnsupported -		} -		// 32 bits per pixel is possibly RGBX (X is padding) or RGBA (A is -		// alpha transparency). However, for BMP images, "Alpha is a -		// poorly-documented and inconsistently-used feature" says -		// https://source.chromium.org/chromium/chromium/src/+/bc0a792d7ebc587190d1a62ccddba10abeea274b:third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc;l=621 -		// -		// That goes on to say "BITMAPV3HEADER+ have an alpha bitmask in the -		// info header... so we respect it at all times... [For earlier -		// (smaller) headers we] ignore alpha in Windows V3 BMPs except inside -		// ICO files". -		// -		// "Ignore" means to always set alpha to 0xFF (fully opaque): -		// https://source.chromium.org/chromium/chromium/src/+/bc0a792d7ebc587190d1a62ccddba10abeea274b:third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.h;l=272 -		// -		// Confusingly, "Windows V3" does not correspond to BITMAPV3HEADER, but -		// instead corresponds to the earlier (smaller) BITMAPINFOHEADER: -		// https://source.chromium.org/chromium/chromium/src/+/bc0a792d7ebc587190d1a62ccddba10abeea274b:third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc;l=258 -		// -		// This Go package does not support ICO files and the (infoLen > -		// infoHeaderLen) condition distinguishes BITMAPINFOHEADER (40 bytes) -		// vs later (larger) headers. -		allowAlpha = infoLen > infoHeaderLen -		return image.Config{ColorModel: color.RGBAModel, Width: width, Height: height}, 32, topDown, allowAlpha, nil -	} -	return image.Config{}, 0, false, false, ErrUnsupported -} - -func init() { -	image.RegisterFormat("bmp", "BM????\x00\x00\x00\x00", Decode, DecodeConfig) -} diff --git a/vendor/golang.org/x/image/bmp/writer.go b/vendor/golang.org/x/image/bmp/writer.go deleted file mode 100644 index f07b39dba..000000000 --- a/vendor/golang.org/x/image/bmp/writer.go +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bmp - -import ( -	"encoding/binary" -	"errors" -	"image" -	"io" -) - -type header struct { -	sigBM           [2]byte -	fileSize        uint32 -	resverved       [2]uint16 -	pixOffset       uint32 -	dibHeaderSize   uint32 -	width           uint32 -	height          uint32 -	colorPlane      uint16 -	bpp             uint16 -	compression     uint32 -	imageSize       uint32 -	xPixelsPerMeter uint32 -	yPixelsPerMeter uint32 -	colorUse        uint32 -	colorImportant  uint32 -} - -func encodePaletted(w io.Writer, pix []uint8, dx, dy, stride, step int) error { -	var padding []byte -	if dx < step { -		padding = make([]byte, step-dx) -	} -	for y := dy - 1; y >= 0; y-- { -		min := y*stride + 0 -		max := y*stride + dx -		if _, err := w.Write(pix[min:max]); err != nil { -			return err -		} -		if padding != nil { -			if _, err := w.Write(padding); err != nil { -				return err -			} -		} -	} -	return nil -} - -func encodeRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int, opaque bool) error { -	buf := make([]byte, step) -	if opaque { -		for y := dy - 1; y >= 0; y-- { -			min := y*stride + 0 -			max := y*stride + dx*4 -			off := 0 -			for i := min; i < max; i += 4 { -				buf[off+2] = pix[i+0] -				buf[off+1] = pix[i+1] -				buf[off+0] = pix[i+2] -				off += 3 -			} -			if _, err := w.Write(buf); err != nil { -				return err -			} -		} -	} else { -		for y := dy - 1; y >= 0; y-- { -			min := y*stride + 0 -			max := y*stride + dx*4 -			off := 0 -			for i := min; i < max; i += 4 { -				a := uint32(pix[i+3]) -				if a == 0 { -					buf[off+2] = 0 -					buf[off+1] = 0 -					buf[off+0] = 0 -					buf[off+3] = 0 -					off += 4 -					continue -				} else if a == 0xff { -					buf[off+2] = pix[i+0] -					buf[off+1] = pix[i+1] -					buf[off+0] = pix[i+2] -					buf[off+3] = 0xff -					off += 4 -					continue -				} -				buf[off+2] = uint8(((uint32(pix[i+0]) * 0xffff) / a) >> 8) -				buf[off+1] = uint8(((uint32(pix[i+1]) * 0xffff) / a) >> 8) -				buf[off+0] = uint8(((uint32(pix[i+2]) * 0xffff) / a) >> 8) -				buf[off+3] = uint8(a) -				off += 4 -			} -			if _, err := w.Write(buf); err != nil { -				return err -			} -		} -	} -	return nil -} - -func encodeNRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int, opaque bool) error { -	buf := make([]byte, step) -	if opaque { -		for y := dy - 1; y >= 0; y-- { -			min := y*stride + 0 -			max := y*stride + dx*4 -			off := 0 -			for i := min; i < max; i += 4 { -				buf[off+2] = pix[i+0] -				buf[off+1] = pix[i+1] -				buf[off+0] = pix[i+2] -				off += 3 -			} -			if _, err := w.Write(buf); err != nil { -				return err -			} -		} -	} else { -		for y := dy - 1; y >= 0; y-- { -			min := y*stride + 0 -			max := y*stride + dx*4 -			off := 0 -			for i := min; i < max; i += 4 { -				buf[off+2] = pix[i+0] -				buf[off+1] = pix[i+1] -				buf[off+0] = pix[i+2] -				buf[off+3] = pix[i+3] -				off += 4 -			} -			if _, err := w.Write(buf); err != nil { -				return err -			} -		} -	} -	return nil -} - -func encode(w io.Writer, m image.Image, step int) error { -	b := m.Bounds() -	buf := make([]byte, step) -	for y := b.Max.Y - 1; y >= b.Min.Y; y-- { -		off := 0 -		for x := b.Min.X; x < b.Max.X; x++ { -			r, g, b, _ := m.At(x, y).RGBA() -			buf[off+2] = byte(r >> 8) -			buf[off+1] = byte(g >> 8) -			buf[off+0] = byte(b >> 8) -			off += 3 -		} -		if _, err := w.Write(buf); err != nil { -			return err -		} -	} -	return nil -} - -// Encode writes the image m to w in BMP format. -func Encode(w io.Writer, m image.Image) error { -	d := m.Bounds().Size() -	if d.X < 0 || d.Y < 0 { -		return errors.New("bmp: negative bounds") -	} -	h := &header{ -		sigBM:         [2]byte{'B', 'M'}, -		fileSize:      14 + 40, -		pixOffset:     14 + 40, -		dibHeaderSize: 40, -		width:         uint32(d.X), -		height:        uint32(d.Y), -		colorPlane:    1, -	} - -	var step int -	var palette []byte -	var opaque bool -	switch m := m.(type) { -	case *image.Gray: -		step = (d.X + 3) &^ 3 -		palette = make([]byte, 1024) -		for i := 0; i < 256; i++ { -			palette[i*4+0] = uint8(i) -			palette[i*4+1] = uint8(i) -			palette[i*4+2] = uint8(i) -			palette[i*4+3] = 0xFF -		} -		h.imageSize = uint32(d.Y * step) -		h.fileSize += uint32(len(palette)) + h.imageSize -		h.pixOffset += uint32(len(palette)) -		h.bpp = 8 - -	case *image.Paletted: -		step = (d.X + 3) &^ 3 -		palette = make([]byte, 1024) -		for i := 0; i < len(m.Palette) && i < 256; i++ { -			r, g, b, _ := m.Palette[i].RGBA() -			palette[i*4+0] = uint8(b >> 8) -			palette[i*4+1] = uint8(g >> 8) -			palette[i*4+2] = uint8(r >> 8) -			palette[i*4+3] = 0xFF -		} -		h.imageSize = uint32(d.Y * step) -		h.fileSize += uint32(len(palette)) + h.imageSize -		h.pixOffset += uint32(len(palette)) -		h.bpp = 8 -	case *image.RGBA: -		opaque = m.Opaque() -		if opaque { -			step = (3*d.X + 3) &^ 3 -			h.bpp = 24 -		} else { -			step = 4 * d.X -			h.bpp = 32 -		} -		h.imageSize = uint32(d.Y * step) -		h.fileSize += h.imageSize -	case *image.NRGBA: -		opaque = m.Opaque() -		if opaque { -			step = (3*d.X + 3) &^ 3 -			h.bpp = 24 -		} else { -			step = 4 * d.X -			h.bpp = 32 -		} -		h.imageSize = uint32(d.Y * step) -		h.fileSize += h.imageSize -	default: -		step = (3*d.X + 3) &^ 3 -		h.imageSize = uint32(d.Y * step) -		h.fileSize += h.imageSize -		h.bpp = 24 -	} - -	if err := binary.Write(w, binary.LittleEndian, h); err != nil { -		return err -	} -	if palette != nil { -		if err := binary.Write(w, binary.LittleEndian, palette); err != nil { -			return err -		} -	} - -	if d.X == 0 || d.Y == 0 { -		return nil -	} - -	switch m := m.(type) { -	case *image.Gray: -		return encodePaletted(w, m.Pix, d.X, d.Y, m.Stride, step) -	case *image.Paletted: -		return encodePaletted(w, m.Pix, d.X, d.Y, m.Stride, step) -	case *image.RGBA: -		return encodeRGBA(w, m.Pix, d.X, d.Y, m.Stride, step, opaque) -	case *image.NRGBA: -		return encodeNRGBA(w, m.Pix, d.X, d.Y, m.Stride, step, opaque) -	} -	return encode(w, m, step) -} diff --git a/vendor/golang.org/x/image/ccitt/reader.go b/vendor/golang.org/x/image/ccitt/reader.go deleted file mode 100644 index 340de0536..000000000 --- a/vendor/golang.org/x/image/ccitt/reader.go +++ /dev/null @@ -1,795 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:generate go run gen.go - -// Package ccitt implements a CCITT (fax) image decoder. -package ccitt - -import ( -	"encoding/binary" -	"errors" -	"image" -	"io" -	"math/bits" -) - -var ( -	errIncompleteCode          = errors.New("ccitt: incomplete code") -	errInvalidBounds           = errors.New("ccitt: invalid bounds") -	errInvalidCode             = errors.New("ccitt: invalid code") -	errInvalidMode             = errors.New("ccitt: invalid mode") -	errInvalidOffset           = errors.New("ccitt: invalid offset") -	errMissingEOL              = errors.New("ccitt: missing End-of-Line") -	errRunLengthOverflowsWidth = errors.New("ccitt: run length overflows width") -	errRunLengthTooLong        = errors.New("ccitt: run length too long") -	errUnsupportedMode         = errors.New("ccitt: unsupported mode") -	errUnsupportedSubFormat    = errors.New("ccitt: unsupported sub-format") -	errUnsupportedWidth        = errors.New("ccitt: unsupported width") -) - -// Order specifies the bit ordering in a CCITT data stream. -type Order uint32 - -const ( -	// LSB means Least Significant Bits first. -	LSB Order = iota -	// MSB means Most Significant Bits first. -	MSB -) - -// SubFormat represents that the CCITT format consists of a number of -// sub-formats. Decoding or encoding a CCITT data stream requires knowing the -// sub-format context. It is not represented in the data stream per se. -type SubFormat uint32 - -const ( -	Group3 SubFormat = iota -	Group4 -) - -// AutoDetectHeight is passed as the height argument to NewReader to indicate -// that the image height (the number of rows) is not known in advance. -const AutoDetectHeight = -1 - -// Options are optional parameters. -type Options struct { -	// Align means that some variable-bit-width codes are byte-aligned. -	Align bool -	// Invert means that black is the 1 bit or 0xFF byte, and white is 0. -	Invert bool -} - -// maxWidth is the maximum (inclusive) supported width. This is a limitation of -// this implementation, to guard against integer overflow, and not anything -// inherent to the CCITT format. -const maxWidth = 1 << 20 - -func invertBytes(b []byte) { -	for i, c := range b { -		b[i] = ^c -	} -} - -func reverseBitsWithinBytes(b []byte) { -	for i, c := range b { -		b[i] = bits.Reverse8(c) -	} -} - -// highBits writes to dst (1 bit per pixel, most significant bit first) the -// high (0x80) bits from src (1 byte per pixel). It returns the number of bytes -// written and read such that dst[:d] is the packed form of src[:s]. -// -// For example, if src starts with the 8 bytes [0x7D, 0x7E, 0x7F, 0x80, 0x81, -// 0x82, 0x00, 0xFF] then 0x1D will be written to dst[0]. -// -// If src has (8 * len(dst)) or more bytes then only len(dst) bytes are -// written, (8 * len(dst)) bytes are read, and invert is ignored. -// -// Otherwise, if len(src) is not a multiple of 8 then the final byte written to -// dst is padded with 1 bits (if invert is true) or 0 bits. If inverted, the 1s -// are typically temporary, e.g. they will be flipped back to 0s by an -// invertBytes call in the highBits caller, reader.Read. -func highBits(dst []byte, src []byte, invert bool) (d int, s int) { -	// Pack as many complete groups of 8 src bytes as we can. -	n := len(src) / 8 -	if n > len(dst) { -		n = len(dst) -	} -	dstN := dst[:n] -	for i := range dstN { -		src8 := src[i*8 : i*8+8] -		dstN[i] = ((src8[0] & 0x80) >> 0) | -			((src8[1] & 0x80) >> 1) | -			((src8[2] & 0x80) >> 2) | -			((src8[3] & 0x80) >> 3) | -			((src8[4] & 0x80) >> 4) | -			((src8[5] & 0x80) >> 5) | -			((src8[6] & 0x80) >> 6) | -			((src8[7] & 0x80) >> 7) -	} -	d, s = n, 8*n -	dst, src = dst[d:], src[s:] - -	// Pack up to 7 remaining src bytes, if there's room in dst. -	if (len(dst) > 0) && (len(src) > 0) { -		dstByte := byte(0) -		if invert { -			dstByte = 0xFF >> uint(len(src)) -		} -		for n, srcByte := range src { -			dstByte |= (srcByte & 0x80) >> uint(n) -		} -		dst[0] = dstByte -		d, s = d+1, s+len(src) -	} -	return d, s -} - -type bitReader struct { -	r io.Reader - -	// readErr is the error returned from the most recent r.Read call. As the -	// io.Reader documentation says, when r.Read returns (n, err), "always -	// process the n > 0 bytes returned before considering the error err". -	readErr error - -	// order is whether to process r's bytes LSB first or MSB first. -	order Order - -	// The high nBits bits of the bits field hold upcoming bits in MSB order. -	bits  uint64 -	nBits uint32 - -	// bytes[br:bw] holds bytes read from r but not yet loaded into bits. -	br    uint32 -	bw    uint32 -	bytes [1024]uint8 -} - -func (b *bitReader) alignToByteBoundary() { -	n := b.nBits & 7 -	b.bits <<= n -	b.nBits -= n -} - -// nextBitMaxNBits is the maximum possible value of bitReader.nBits after a -// bitReader.nextBit call, provided that bitReader.nBits was not more than this -// value before that call. -// -// Note that the decode function can unread bits, which can temporarily set the -// bitReader.nBits value above nextBitMaxNBits. -const nextBitMaxNBits = 31 - -func (b *bitReader) nextBit() (uint64, error) { -	for { -		if b.nBits > 0 { -			bit := b.bits >> 63 -			b.bits <<= 1 -			b.nBits-- -			return bit, nil -		} - -		if available := b.bw - b.br; available >= 4 { -			// Read 32 bits, even though b.bits is a uint64, since the decode -			// function may need to unread up to maxCodeLength bits, putting -			// them back in the remaining (64 - 32) bits. TestMaxCodeLength -			// checks that the generated maxCodeLength constant fits. -			// -			// If changing the Uint32 call, also change nextBitMaxNBits. -			b.bits = uint64(binary.BigEndian.Uint32(b.bytes[b.br:])) << 32 -			b.br += 4 -			b.nBits = 32 -			continue -		} else if available > 0 { -			b.bits = uint64(b.bytes[b.br]) << (7 * 8) -			b.br++ -			b.nBits = 8 -			continue -		} - -		if b.readErr != nil { -			return 0, b.readErr -		} - -		n, err := b.r.Read(b.bytes[:]) -		b.br = 0 -		b.bw = uint32(n) -		b.readErr = err - -		if b.order != MSB { -			reverseBitsWithinBytes(b.bytes[:b.bw]) -		} -	} -} - -func decode(b *bitReader, decodeTable [][2]int16) (uint32, error) { -	nBitsRead, bitsRead, state := uint32(0), uint64(0), int32(1) -	for { -		bit, err := b.nextBit() -		if err != nil { -			if err == io.EOF { -				err = errIncompleteCode -			} -			return 0, err -		} -		bitsRead |= bit << (63 - nBitsRead) -		nBitsRead++ - -		// The "&1" is redundant, but can eliminate a bounds check. -		state = int32(decodeTable[state][bit&1]) -		if state < 0 { -			return uint32(^state), nil -		} else if state == 0 { -			// Unread the bits we've read, then return errInvalidCode. -			b.bits = (b.bits >> nBitsRead) | bitsRead -			b.nBits += nBitsRead -			return 0, errInvalidCode -		} -	} -} - -// decodeEOL decodes the 12-bit EOL code 0000_0000_0001. -func decodeEOL(b *bitReader) error { -	nBitsRead, bitsRead := uint32(0), uint64(0) -	for { -		bit, err := b.nextBit() -		if err != nil { -			if err == io.EOF { -				err = errMissingEOL -			} -			return err -		} -		bitsRead |= bit << (63 - nBitsRead) -		nBitsRead++ - -		if nBitsRead < 12 { -			if bit&1 == 0 { -				continue -			} -		} else if bit&1 != 0 { -			return nil -		} - -		// Unread the bits we've read, then return errMissingEOL. -		b.bits = (b.bits >> nBitsRead) | bitsRead -		b.nBits += nBitsRead -		return errMissingEOL -	} -} - -type reader struct { -	br        bitReader -	subFormat SubFormat - -	// width is the image width in pixels. -	width int - -	// rowsRemaining starts at the image height in pixels, when the reader is -	// driven through the io.Reader interface, and decrements to zero as rows -	// are decoded. Alternatively, it may be negative if the image height is -	// not known in advance at the time of the NewReader call. -	// -	// When driven through DecodeIntoGray, this field is unused. -	rowsRemaining int - -	// curr and prev hold the current and previous rows. Each element is either -	// 0x00 (black) or 0xFF (white). -	// -	// prev may be nil, when processing the first row. -	curr []byte -	prev []byte - -	// ri is the read index. curr[:ri] are those bytes of curr that have been -	// passed along via the Read method. -	// -	// When the reader is driven through DecodeIntoGray, instead of through the -	// io.Reader interface, this field is unused. -	ri int - -	// wi is the write index. curr[:wi] are those bytes of curr that have -	// already been decoded via the decodeRow method. -	// -	// What this implementation calls wi is roughly equivalent to what the spec -	// calls the a0 index. -	wi int - -	// These fields are copied from the *Options (which may be nil). -	align  bool -	invert bool - -	// atStartOfRow is whether we have just started the row. Some parts of the -	// spec say to treat this situation as if "wi = -1". -	atStartOfRow bool - -	// penColorIsWhite is whether the next run is black or white. -	penColorIsWhite bool - -	// seenStartOfImage is whether we've called the startDecode method. -	seenStartOfImage bool - -	// truncated is whether the input is missing the final 6 consecutive EOL's -	// (for Group3) or 2 consecutive EOL's (for Group4). Omitting that trailer -	// (but otherwise padding to a byte boundary, with either all 0 bits or all -	// 1 bits) is invalid according to the spec, but happens in practice when -	// exporting from Adobe Acrobat to TIFF + CCITT. This package silently -	// ignores the format error for CCITT input that has been truncated in that -	// fashion, returning the full decoded image. -	// -	// Detecting trailer truncation (just after the final row of pixels) -	// requires knowing which row is the final row, and therefore does not -	// trigger if the image height is not known in advance. -	truncated bool - -	// readErr is a sticky error for the Read method. -	readErr error -} - -func (z *reader) Read(p []byte) (int, error) { -	if z.readErr != nil { -		return 0, z.readErr -	} -	originalP := p - -	for len(p) > 0 { -		// Allocate buffers (and decode any start-of-image codes), if -		// processing the first or second row. -		if z.curr == nil { -			if !z.seenStartOfImage { -				if z.readErr = z.startDecode(); z.readErr != nil { -					break -				} -				z.atStartOfRow = true -			} -			z.curr = make([]byte, z.width) -		} - -		// Decode the next row, if necessary. -		if z.atStartOfRow { -			if z.rowsRemaining < 0 { -				// We do not know the image height in advance. See if the next -				// code is an EOL. If it is, it is consumed. If it isn't, the -				// bitReader shouldn't advance along the bit stream, and we -				// simply decode another row of pixel data. -				// -				// For the Group4 subFormat, we may need to align to a byte -				// boundary. For the Group3 subFormat, the previous z.decodeRow -				// call (or z.startDecode call) has already consumed one of the -				// 6 consecutive EOL's. The next EOL is actually the second of -				// 6, in the middle, and we shouldn't align at that point. -				if z.align && (z.subFormat == Group4) { -					z.br.alignToByteBoundary() -				} - -				if err := z.decodeEOL(); err == errMissingEOL { -					// No-op. It's another row of pixel data. -				} else if err != nil { -					z.readErr = err -					break -				} else { -					if z.readErr = z.finishDecode(true); z.readErr != nil { -						break -					} -					z.readErr = io.EOF -					break -				} - -			} else if z.rowsRemaining == 0 { -				// We do know the image height in advance, and we have already -				// decoded exactly that many rows. -				if z.readErr = z.finishDecode(false); z.readErr != nil { -					break -				} -				z.readErr = io.EOF -				break - -			} else { -				z.rowsRemaining-- -			} - -			if z.readErr = z.decodeRow(z.rowsRemaining == 0); z.readErr != nil { -				break -			} -		} - -		// Pack from z.curr (1 byte per pixel) to p (1 bit per pixel). -		packD, packS := highBits(p, z.curr[z.ri:], z.invert) -		p = p[packD:] -		z.ri += packS - -		// Prepare to decode the next row, if necessary. -		if z.ri == len(z.curr) { -			z.ri, z.curr, z.prev = 0, z.prev, z.curr -			z.atStartOfRow = true -		} -	} - -	n := len(originalP) - len(p) -	if z.invert { -		invertBytes(originalP[:n]) -	} -	return n, z.readErr -} - -func (z *reader) penColor() byte { -	if z.penColorIsWhite { -		return 0xFF -	} -	return 0x00 -} - -func (z *reader) startDecode() error { -	switch z.subFormat { -	case Group3: -		if err := z.decodeEOL(); err != nil { -			return err -		} - -	case Group4: -		// No-op. - -	default: -		return errUnsupportedSubFormat -	} - -	z.seenStartOfImage = true -	return nil -} - -func (z *reader) finishDecode(alreadySeenEOL bool) error { -	numberOfEOLs := 0 -	switch z.subFormat { -	case Group3: -		if z.truncated { -			return nil -		} -		// The stream ends with a RTC (Return To Control) of 6 consecutive -		// EOL's, but we should have already just seen an EOL, either in -		// z.startDecode (for a zero-height image) or in z.decodeRow. -		numberOfEOLs = 5 - -	case Group4: -		autoDetectHeight := z.rowsRemaining < 0 -		if autoDetectHeight { -			// Aligning to a byte boundary was already handled by reader.Read. -		} else if z.align { -			z.br.alignToByteBoundary() -		} -		// The stream ends with two EOL's. If the first one is missing, and we -		// had an explicit image height, we just assume that the trailing two -		// EOL's were truncated and return a nil error. -		if err := z.decodeEOL(); err != nil { -			if (err == errMissingEOL) && !autoDetectHeight { -				z.truncated = true -				return nil -			} -			return err -		} -		numberOfEOLs = 1 - -	default: -		return errUnsupportedSubFormat -	} - -	if alreadySeenEOL { -		numberOfEOLs-- -	} -	for ; numberOfEOLs > 0; numberOfEOLs-- { -		if err := z.decodeEOL(); err != nil { -			return err -		} -	} -	return nil -} - -func (z *reader) decodeEOL() error { -	return decodeEOL(&z.br) -} - -func (z *reader) decodeRow(finalRow bool) error { -	z.wi = 0 -	z.atStartOfRow = true -	z.penColorIsWhite = true - -	if z.align { -		z.br.alignToByteBoundary() -	} - -	switch z.subFormat { -	case Group3: -		for ; z.wi < len(z.curr); z.atStartOfRow = false { -			if err := z.decodeRun(); err != nil { -				return err -			} -		} -		err := z.decodeEOL() -		if finalRow && (err == errMissingEOL) { -			z.truncated = true -			return nil -		} -		return err - -	case Group4: -		for ; z.wi < len(z.curr); z.atStartOfRow = false { -			mode, err := decode(&z.br, modeDecodeTable[:]) -			if err != nil { -				return err -			} -			rm := readerMode{} -			if mode < uint32(len(readerModes)) { -				rm = readerModes[mode] -			} -			if rm.function == nil { -				return errInvalidMode -			} -			if err := rm.function(z, rm.arg); err != nil { -				return err -			} -		} -		return nil -	} - -	return errUnsupportedSubFormat -} - -func (z *reader) decodeRun() error { -	table := blackDecodeTable[:] -	if z.penColorIsWhite { -		table = whiteDecodeTable[:] -	} - -	total := 0 -	for { -		n, err := decode(&z.br, table) -		if err != nil { -			return err -		} -		if n > maxWidth { -			panic("unreachable") -		} -		total += int(n) -		if total > maxWidth { -			return errRunLengthTooLong -		} -		// Anything 0x3F or below is a terminal code. -		if n <= 0x3F { -			break -		} -	} - -	if total > (len(z.curr) - z.wi) { -		return errRunLengthOverflowsWidth -	} -	dst := z.curr[z.wi : z.wi+total] -	penColor := z.penColor() -	for i := range dst { -		dst[i] = penColor -	} -	z.wi += total -	z.penColorIsWhite = !z.penColorIsWhite - -	return nil -} - -// The various modes' semantics are based on determining a row of pixels' -// "changing elements": those pixels whose color differs from the one on its -// immediate left. -// -// The row above the first row is implicitly all white. Similarly, the column -// to the left of the first column is implicitly all white. -// -// For example, here's Figure 1 in "ITU-T Recommendation T.6", where the -// current and previous rows contain black (B) and white (w) pixels. The a? -// indexes point into curr, the b? indexes point into prev. -// -//                 b1 b2 -//                 v  v -// prev: BBBBBwwwwwBBBwwwww -// curr: BBBwwwwwBBBBBBwwww -//          ^    ^     ^ -//          a0   a1    a2 -// -// a0 is the "reference element" or current decoder position, roughly -// equivalent to what this implementation calls reader.wi. -// -// a1 is the next changing element to the right of a0, on the "coding line" -// (the current row). -// -// a2 is the next changing element to the right of a1, again on curr. -// -// b1 is the first changing element on the "reference line" (the previous row) -// to the right of a0 and of opposite color to a0. -// -// b2 is the next changing element to the right of b1, again on prev. -// -// The various modes calculate a1 (and a2, for modeH): -//  - modePass calculates that a1 is at or to the right of b2. -//  - modeH    calculates a1 and a2 without considering b1 or b2. -//  - modeV*   calculates a1 to be b1 plus an adjustment (between -3 and +3). - -const ( -	findB1 = false -	findB2 = true -) - -// findB finds either the b1 or b2 value. -func (z *reader) findB(whichB bool) int { -	// The initial row is a special case. The previous row is implicitly all -	// white, so that there are no changing pixel elements. We return b1 or b2 -	// to be at the end of the row. -	if len(z.prev) != len(z.curr) { -		return len(z.curr) -	} - -	i := z.wi - -	if z.atStartOfRow { -		// a0 is implicitly at -1, on a white pixel. b1 is the first black -		// pixel in the previous row. b2 is the first white pixel after that. -		for ; (i < len(z.prev)) && (z.prev[i] == 0xFF); i++ { -		} -		if whichB == findB2 { -			for ; (i < len(z.prev)) && (z.prev[i] == 0x00); i++ { -			} -		} -		return i -	} - -	// As per figure 1 above, assume that the current pen color is white. -	// First, walk past every contiguous black pixel in prev, starting at a0. -	oppositeColor := ^z.penColor() -	for ; (i < len(z.prev)) && (z.prev[i] == oppositeColor); i++ { -	} - -	// Then walk past every contiguous white pixel. -	penColor := ^oppositeColor -	for ; (i < len(z.prev)) && (z.prev[i] == penColor); i++ { -	} - -	// We're now at a black pixel (or at the end of the row). That's b1. -	if whichB == findB2 { -		// If we're looking for b2, walk past every contiguous black pixel -		// again. -		oppositeColor := ^penColor -		for ; (i < len(z.prev)) && (z.prev[i] == oppositeColor); i++ { -		} -	} - -	return i -} - -type readerMode struct { -	function func(z *reader, arg int) error -	arg      int -} - -var readerModes = [...]readerMode{ -	modePass: {function: readerModePass}, -	modeH:    {function: readerModeH}, -	modeV0:   {function: readerModeV, arg: +0}, -	modeVR1:  {function: readerModeV, arg: +1}, -	modeVR2:  {function: readerModeV, arg: +2}, -	modeVR3:  {function: readerModeV, arg: +3}, -	modeVL1:  {function: readerModeV, arg: -1}, -	modeVL2:  {function: readerModeV, arg: -2}, -	modeVL3:  {function: readerModeV, arg: -3}, -	modeExt:  {function: readerModeExt}, -} - -func readerModePass(z *reader, arg int) error { -	b2 := z.findB(findB2) -	if (b2 < z.wi) || (len(z.curr) < b2) { -		return errInvalidOffset -	} -	dst := z.curr[z.wi:b2] -	penColor := z.penColor() -	for i := range dst { -		dst[i] = penColor -	} -	z.wi = b2 -	return nil -} - -func readerModeH(z *reader, arg int) error { -	// The first iteration finds a1. The second finds a2. -	for i := 0; i < 2; i++ { -		if err := z.decodeRun(); err != nil { -			return err -		} -	} -	return nil -} - -func readerModeV(z *reader, arg int) error { -	a1 := z.findB(findB1) + arg -	if (a1 < z.wi) || (len(z.curr) < a1) { -		return errInvalidOffset -	} -	dst := z.curr[z.wi:a1] -	penColor := z.penColor() -	for i := range dst { -		dst[i] = penColor -	} -	z.wi = a1 -	z.penColorIsWhite = !z.penColorIsWhite -	return nil -} - -func readerModeExt(z *reader, arg int) error { -	return errUnsupportedMode -} - -// DecodeIntoGray decodes the CCITT-formatted data in r into dst. -// -// It returns an error if dst's width and height don't match the implied width -// and height of CCITT-formatted data. -func DecodeIntoGray(dst *image.Gray, r io.Reader, order Order, sf SubFormat, opts *Options) error { -	bounds := dst.Bounds() -	if (bounds.Dx() < 0) || (bounds.Dy() < 0) { -		return errInvalidBounds -	} -	if bounds.Dx() > maxWidth { -		return errUnsupportedWidth -	} - -	z := reader{ -		br:        bitReader{r: r, order: order}, -		subFormat: sf, -		align:     (opts != nil) && opts.Align, -		invert:    (opts != nil) && opts.Invert, -		width:     bounds.Dx(), -	} -	if err := z.startDecode(); err != nil { -		return err -	} - -	width := bounds.Dx() -	for y := bounds.Min.Y; y < bounds.Max.Y; y++ { -		p := (y - bounds.Min.Y) * dst.Stride -		z.curr = dst.Pix[p : p+width] -		if err := z.decodeRow(y+1 == bounds.Max.Y); err != nil { -			return err -		} -		z.curr, z.prev = nil, z.curr -	} - -	if err := z.finishDecode(false); err != nil { -		return err -	} - -	if z.invert { -		for y := bounds.Min.Y; y < bounds.Max.Y; y++ { -			p := (y - bounds.Min.Y) * dst.Stride -			invertBytes(dst.Pix[p : p+width]) -		} -	} - -	return nil -} - -// NewReader returns an io.Reader that decodes the CCITT-formatted data in r. -// The resultant byte stream is one bit per pixel (MSB first), with 1 meaning -// white and 0 meaning black. Each row in the result is byte-aligned. -// -// A negative height, such as passing AutoDetectHeight, means that the image -// height is not known in advance. A negative width is invalid. -func NewReader(r io.Reader, order Order, sf SubFormat, width int, height int, opts *Options) io.Reader { -	readErr := error(nil) -	if width < 0 { -		readErr = errInvalidBounds -	} else if width > maxWidth { -		readErr = errUnsupportedWidth -	} - -	return &reader{ -		br:            bitReader{r: r, order: order}, -		subFormat:     sf, -		align:         (opts != nil) && opts.Align, -		invert:        (opts != nil) && opts.Invert, -		width:         width, -		rowsRemaining: height, -		readErr:       readErr, -	} -} diff --git a/vendor/golang.org/x/image/ccitt/table.go b/vendor/golang.org/x/image/ccitt/table.go deleted file mode 100644 index 8b3794bc2..000000000 --- a/vendor/golang.org/x/image/ccitt/table.go +++ /dev/null @@ -1,972 +0,0 @@ -// generated by "go run gen.go". DO NOT EDIT. - -package ccitt - -// Each decodeTable is represented by an array of [2]int16's: a binary tree. -// Each array element (other than element 0, which means invalid) is a branch -// node in that tree. The root node is always element 1 (the second element). -// -// To walk the tree, look at the next bit in the bit stream, using it to select -// the first or second element of the [2]int16. If that int16 is 0, we have an -// invalid code. If it is positive, go to that branch node. If it is negative, -// then we have a leaf node, whose value is the bitwise complement (the ^ -// operator) of that int16. -// -// Comments above each decodeTable also show the same structure visually. The -// "b123" lines show the 123'rd branch node. The "=XXXXX" lines show an invalid -// code. The "=v1234" lines show a leaf node with value 1234. When reading the -// bit stream, a 0 or 1 bit means to go up or down, as you move left to right. -// -// For example, in modeDecodeTable, branch node b005 is three steps up from the -// root node, meaning that we have already seen "000". If the next bit is "0" -// then we move to branch node b006. Otherwise, the next bit is "1", and we -// move to the leaf node v0000 (also known as the modePass constant). Indeed, -// the bits that encode modePass are "0001". -// -// Tables 1, 2 and 3 come from the "ITU-T Recommendation T.6: FACSIMILE CODING -// SCHEMES AND CODING CONTROL FUNCTIONS FOR GROUP 4 FACSIMILE APPARATUS" -// specification: -// -// https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-T.6-198811-I!!PDF-E&type=items - -// modeDecodeTable represents Table 1 and the End-of-Line code. -// -//	                   +=XXXXX -//	b009             +-+ -//	                 | +=v0009 -//	b007           +-+ -//	               | | +=v0008 -//	b010           | +-+ -//	               |   +=v0005 -//	b006         +-+ -//	             | | +=v0007 -//	b008         | +-+ -//	             |   +=v0004 -//	b005       +-+ -//	           | +=v0000 -//	b003     +-+ -//	         | +=v0001 -//	b002   +-+ -//	       | | +=v0006 -//	b004   | +-+ -//	       |   +=v0003 -//	b001 +-+ -//	       +=v0002 -var modeDecodeTable = [...][2]int16{ -	0:  {0, 0}, -	1:  {2, ^2}, -	2:  {3, 4}, -	3:  {5, ^1}, -	4:  {^6, ^3}, -	5:  {6, ^0}, -	6:  {7, 8}, -	7:  {9, 10}, -	8:  {^7, ^4}, -	9:  {0, ^9}, -	10: {^8, ^5}, -} - -// whiteDecodeTable represents Tables 2 and 3 for a white run. -// -//	                     +=XXXXX -//	b059               +-+ -//	                   | |     +=v1792 -//	b096               | |   +-+ -//	                   | |   | | +=v1984 -//	b100               | |   | +-+ -//	                   | |   |   +=v2048 -//	b094               | | +-+ -//	                   | | | |   +=v2112 -//	b101               | | | | +-+ -//	                   | | | | | +=v2176 -//	b097               | | | +-+ -//	                   | | |   | +=v2240 -//	b102               | | |   +-+ -//	                   | | |     +=v2304 -//	b085               | +-+ -//	                   |   |   +=v1856 -//	b098               |   | +-+ -//	                   |   | | +=v1920 -//	b095               |   +-+ -//	                   |     |   +=v2368 -//	b103               |     | +-+ -//	                   |     | | +=v2432 -//	b099               |     +-+ -//	                   |       | +=v2496 -//	b104               |       +-+ -//	                   |         +=v2560 -//	b040             +-+ -//	                 | | +=v0029 -//	b060             | +-+ -//	                 |   +=v0030 -//	b026           +-+ -//	               | |   +=v0045 -//	b061           | | +-+ -//	               | | | +=v0046 -//	b041           | +-+ -//	               |   +=v0022 -//	b016         +-+ -//	             | |   +=v0023 -//	b042         | | +-+ -//	             | | | | +=v0047 -//	b062         | | | +-+ -//	             | | |   +=v0048 -//	b027         | +-+ -//	             |   +=v0013 -//	b008       +-+ -//	           | |     +=v0020 -//	b043       | |   +-+ -//	           | |   | | +=v0033 -//	b063       | |   | +-+ -//	           | |   |   +=v0034 -//	b028       | | +-+ -//	           | | | |   +=v0035 -//	b064       | | | | +-+ -//	           | | | | | +=v0036 -//	b044       | | | +-+ -//	           | | |   | +=v0037 -//	b065       | | |   +-+ -//	           | | |     +=v0038 -//	b017       | +-+ -//	           |   |   +=v0019 -//	b045       |   | +-+ -//	           |   | | | +=v0031 -//	b066       |   | | +-+ -//	           |   | |   +=v0032 -//	b029       |   +-+ -//	           |     +=v0001 -//	b004     +-+ -//	         | |     +=v0012 -//	b030     | |   +-+ -//	         | |   | |   +=v0053 -//	b067     | |   | | +-+ -//	         | |   | | | +=v0054 -//	b046     | |   | +-+ -//	         | |   |   +=v0026 -//	b018     | | +-+ -//	         | | | |     +=v0039 -//	b068     | | | |   +-+ -//	         | | | |   | +=v0040 -//	b047     | | | | +-+ -//	         | | | | | | +=v0041 -//	b069     | | | | | +-+ -//	         | | | | |   +=v0042 -//	b031     | | | +-+ -//	         | | |   |   +=v0043 -//	b070     | | |   | +-+ -//	         | | |   | | +=v0044 -//	b048     | | |   +-+ -//	         | | |     +=v0021 -//	b009     | +-+ -//	         |   |     +=v0028 -//	b049     |   |   +-+ -//	         |   |   | | +=v0061 -//	b071     |   |   | +-+ -//	         |   |   |   +=v0062 -//	b032     |   | +-+ -//	         |   | | |   +=v0063 -//	b072     |   | | | +-+ -//	         |   | | | | +=v0000 -//	b050     |   | | +-+ -//	         |   | |   | +=v0320 -//	b073     |   | |   +-+ -//	         |   | |     +=v0384 -//	b019     |   +-+ -//	         |     +=v0010 -//	b002   +-+ -//	       | |     +=v0011 -//	b020   | |   +-+ -//	       | |   | |   +=v0027 -//	b051   | |   | | +-+ -//	       | |   | | | | +=v0059 -//	b074   | |   | | | +-+ -//	       | |   | | |   +=v0060 -//	b033   | |   | +-+ -//	       | |   |   |     +=v1472 -//	b086   | |   |   |   +-+ -//	       | |   |   |   | +=v1536 -//	b075   | |   |   | +-+ -//	       | |   |   | | | +=v1600 -//	b087   | |   |   | | +-+ -//	       | |   |   | |   +=v1728 -//	b052   | |   |   +-+ -//	       | |   |     +=v0018 -//	b010   | | +-+ -//	       | | | |     +=v0024 -//	b053   | | | |   +-+ -//	       | | | |   | | +=v0049 -//	b076   | | | |   | +-+ -//	       | | | |   |   +=v0050 -//	b034   | | | | +-+ -//	       | | | | | |   +=v0051 -//	b077   | | | | | | +-+ -//	       | | | | | | | +=v0052 -//	b054   | | | | | +-+ -//	       | | | | |   +=v0025 -//	b021   | | | +-+ -//	       | | |   |     +=v0055 -//	b078   | | |   |   +-+ -//	       | | |   |   | +=v0056 -//	b055   | | |   | +-+ -//	       | | |   | | | +=v0057 -//	b079   | | |   | | +-+ -//	       | | |   | |   +=v0058 -//	b035   | | |   +-+ -//	       | | |     +=v0192 -//	b005   | +-+ -//	       |   |     +=v1664 -//	b036   |   |   +-+ -//	       |   |   | |   +=v0448 -//	b080   |   |   | | +-+ -//	       |   |   | | | +=v0512 -//	b056   |   |   | +-+ -//	       |   |   |   |   +=v0704 -//	b088   |   |   |   | +-+ -//	       |   |   |   | | +=v0768 -//	b081   |   |   |   +-+ -//	       |   |   |     +=v0640 -//	b022   |   | +-+ -//	       |   | | |     +=v0576 -//	b082   |   | | |   +-+ -//	       |   | | |   | | +=v0832 -//	b089   |   | | |   | +-+ -//	       |   | | |   |   +=v0896 -//	b057   |   | | | +-+ -//	       |   | | | | |   +=v0960 -//	b090   |   | | | | | +-+ -//	       |   | | | | | | +=v1024 -//	b083   |   | | | | +-+ -//	       |   | | | |   | +=v1088 -//	b091   |   | | | |   +-+ -//	       |   | | | |     +=v1152 -//	b037   |   | | +-+ -//	       |   | |   |     +=v1216 -//	b092   |   | |   |   +-+ -//	       |   | |   |   | +=v1280 -//	b084   |   | |   | +-+ -//	       |   | |   | | | +=v1344 -//	b093   |   | |   | | +-+ -//	       |   | |   | |   +=v1408 -//	b058   |   | |   +-+ -//	       |   | |     +=v0256 -//	b011   |   +-+ -//	       |     +=v0002 -//	b001 +-+ -//	       |     +=v0003 -//	b012   |   +-+ -//	       |   | | +=v0128 -//	b023   |   | +-+ -//	       |   |   +=v0008 -//	b006   | +-+ -//	       | | |   +=v0009 -//	b024   | | | +-+ -//	       | | | | | +=v0016 -//	b038   | | | | +-+ -//	       | | | |   +=v0017 -//	b013   | | +-+ -//	       | |   +=v0004 -//	b003   +-+ -//	         |   +=v0005 -//	b014     | +-+ -//	         | | |   +=v0014 -//	b039     | | | +-+ -//	         | | | | +=v0015 -//	b025     | | +-+ -//	         | |   +=v0064 -//	b007     +-+ -//	           | +=v0006 -//	b015       +-+ -//	             +=v0007 -var whiteDecodeTable = [...][2]int16{ -	0:   {0, 0}, -	1:   {2, 3}, -	2:   {4, 5}, -	3:   {6, 7}, -	4:   {8, 9}, -	5:   {10, 11}, -	6:   {12, 13}, -	7:   {14, 15}, -	8:   {16, 17}, -	9:   {18, 19}, -	10:  {20, 21}, -	11:  {22, ^2}, -	12:  {^3, 23}, -	13:  {24, ^4}, -	14:  {^5, 25}, -	15:  {^6, ^7}, -	16:  {26, 27}, -	17:  {28, 29}, -	18:  {30, 31}, -	19:  {32, ^10}, -	20:  {^11, 33}, -	21:  {34, 35}, -	22:  {36, 37}, -	23:  {^128, ^8}, -	24:  {^9, 38}, -	25:  {39, ^64}, -	26:  {40, 41}, -	27:  {42, ^13}, -	28:  {43, 44}, -	29:  {45, ^1}, -	30:  {^12, 46}, -	31:  {47, 48}, -	32:  {49, 50}, -	33:  {51, 52}, -	34:  {53, 54}, -	35:  {55, ^192}, -	36:  {^1664, 56}, -	37:  {57, 58}, -	38:  {^16, ^17}, -	39:  {^14, ^15}, -	40:  {59, 60}, -	41:  {61, ^22}, -	42:  {^23, 62}, -	43:  {^20, 63}, -	44:  {64, 65}, -	45:  {^19, 66}, -	46:  {67, ^26}, -	47:  {68, 69}, -	48:  {70, ^21}, -	49:  {^28, 71}, -	50:  {72, 73}, -	51:  {^27, 74}, -	52:  {75, ^18}, -	53:  {^24, 76}, -	54:  {77, ^25}, -	55:  {78, 79}, -	56:  {80, 81}, -	57:  {82, 83}, -	58:  {84, ^256}, -	59:  {0, 85}, -	60:  {^29, ^30}, -	61:  {^45, ^46}, -	62:  {^47, ^48}, -	63:  {^33, ^34}, -	64:  {^35, ^36}, -	65:  {^37, ^38}, -	66:  {^31, ^32}, -	67:  {^53, ^54}, -	68:  {^39, ^40}, -	69:  {^41, ^42}, -	70:  {^43, ^44}, -	71:  {^61, ^62}, -	72:  {^63, ^0}, -	73:  {^320, ^384}, -	74:  {^59, ^60}, -	75:  {86, 87}, -	76:  {^49, ^50}, -	77:  {^51, ^52}, -	78:  {^55, ^56}, -	79:  {^57, ^58}, -	80:  {^448, ^512}, -	81:  {88, ^640}, -	82:  {^576, 89}, -	83:  {90, 91}, -	84:  {92, 93}, -	85:  {94, 95}, -	86:  {^1472, ^1536}, -	87:  {^1600, ^1728}, -	88:  {^704, ^768}, -	89:  {^832, ^896}, -	90:  {^960, ^1024}, -	91:  {^1088, ^1152}, -	92:  {^1216, ^1280}, -	93:  {^1344, ^1408}, -	94:  {96, 97}, -	95:  {98, 99}, -	96:  {^1792, 100}, -	97:  {101, 102}, -	98:  {^1856, ^1920}, -	99:  {103, 104}, -	100: {^1984, ^2048}, -	101: {^2112, ^2176}, -	102: {^2240, ^2304}, -	103: {^2368, ^2432}, -	104: {^2496, ^2560}, -} - -// blackDecodeTable represents Tables 2 and 3 for a black run. -// -//	                     +=XXXXX -//	b017               +-+ -//	                   | |     +=v1792 -//	b042               | |   +-+ -//	                   | |   | | +=v1984 -//	b063               | |   | +-+ -//	                   | |   |   +=v2048 -//	b029               | | +-+ -//	                   | | | |   +=v2112 -//	b064               | | | | +-+ -//	                   | | | | | +=v2176 -//	b043               | | | +-+ -//	                   | | |   | +=v2240 -//	b065               | | |   +-+ -//	                   | | |     +=v2304 -//	b022               | +-+ -//	                   |   |   +=v1856 -//	b044               |   | +-+ -//	                   |   | | +=v1920 -//	b030               |   +-+ -//	                   |     |   +=v2368 -//	b066               |     | +-+ -//	                   |     | | +=v2432 -//	b045               |     +-+ -//	                   |       | +=v2496 -//	b067               |       +-+ -//	                   |         +=v2560 -//	b013             +-+ -//	                 | |     +=v0018 -//	b031             | |   +-+ -//	                 | |   | |   +=v0052 -//	b068             | |   | | +-+ -//	                 | |   | | | | +=v0640 -//	b095             | |   | | | +-+ -//	                 | |   | | |   +=v0704 -//	b046             | |   | +-+ -//	                 | |   |   |   +=v0768 -//	b096             | |   |   | +-+ -//	                 | |   |   | | +=v0832 -//	b069             | |   |   +-+ -//	                 | |   |     +=v0055 -//	b023             | | +-+ -//	                 | | | |     +=v0056 -//	b070             | | | |   +-+ -//	                 | | | |   | | +=v1280 -//	b097             | | | |   | +-+ -//	                 | | | |   |   +=v1344 -//	b047             | | | | +-+ -//	                 | | | | | |   +=v1408 -//	b098             | | | | | | +-+ -//	                 | | | | | | | +=v1472 -//	b071             | | | | | +-+ -//	                 | | | | |   +=v0059 -//	b032             | | | +-+ -//	                 | | |   |   +=v0060 -//	b072             | | |   | +-+ -//	                 | | |   | | | +=v1536 -//	b099             | | |   | | +-+ -//	                 | | |   | |   +=v1600 -//	b048             | | |   +-+ -//	                 | | |     +=v0024 -//	b018             | +-+ -//	                 |   |     +=v0025 -//	b049             |   |   +-+ -//	                 |   |   | |   +=v1664 -//	b100             |   |   | | +-+ -//	                 |   |   | | | +=v1728 -//	b073             |   |   | +-+ -//	                 |   |   |   +=v0320 -//	b033             |   | +-+ -//	                 |   | | |   +=v0384 -//	b074             |   | | | +-+ -//	                 |   | | | | +=v0448 -//	b050             |   | | +-+ -//	                 |   | |   |   +=v0512 -//	b101             |   | |   | +-+ -//	                 |   | |   | | +=v0576 -//	b075             |   | |   +-+ -//	                 |   | |     +=v0053 -//	b024             |   +-+ -//	                 |     |     +=v0054 -//	b076             |     |   +-+ -//	                 |     |   | | +=v0896 -//	b102             |     |   | +-+ -//	                 |     |   |   +=v0960 -//	b051             |     | +-+ -//	                 |     | | |   +=v1024 -//	b103             |     | | | +-+ -//	                 |     | | | | +=v1088 -//	b077             |     | | +-+ -//	                 |     | |   | +=v1152 -//	b104             |     | |   +-+ -//	                 |     | |     +=v1216 -//	b034             |     +-+ -//	                 |       +=v0064 -//	b010           +-+ -//	               | |   +=v0013 -//	b019           | | +-+ -//	               | | | |     +=v0023 -//	b052           | | | |   +-+ -//	               | | | |   | | +=v0050 -//	b078           | | | |   | +-+ -//	               | | | |   |   +=v0051 -//	b035           | | | | +-+ -//	               | | | | | |   +=v0044 -//	b079           | | | | | | +-+ -//	               | | | | | | | +=v0045 -//	b053           | | | | | +-+ -//	               | | | | |   | +=v0046 -//	b080           | | | | |   +-+ -//	               | | | | |     +=v0047 -//	b025           | | | +-+ -//	               | | |   |     +=v0057 -//	b081           | | |   |   +-+ -//	               | | |   |   | +=v0058 -//	b054           | | |   | +-+ -//	               | | |   | | | +=v0061 -//	b082           | | |   | | +-+ -//	               | | |   | |   +=v0256 -//	b036           | | |   +-+ -//	               | | |     +=v0016 -//	b014           | +-+ -//	               |   |     +=v0017 -//	b037           |   |   +-+ -//	               |   |   | |   +=v0048 -//	b083           |   |   | | +-+ -//	               |   |   | | | +=v0049 -//	b055           |   |   | +-+ -//	               |   |   |   | +=v0062 -//	b084           |   |   |   +-+ -//	               |   |   |     +=v0063 -//	b026           |   | +-+ -//	               |   | | |     +=v0030 -//	b085           |   | | |   +-+ -//	               |   | | |   | +=v0031 -//	b056           |   | | | +-+ -//	               |   | | | | | +=v0032 -//	b086           |   | | | | +-+ -//	               |   | | | |   +=v0033 -//	b038           |   | | +-+ -//	               |   | |   |   +=v0040 -//	b087           |   | |   | +-+ -//	               |   | |   | | +=v0041 -//	b057           |   | |   +-+ -//	               |   | |     +=v0022 -//	b020           |   +-+ -//	               |     +=v0014 -//	b008         +-+ -//	             | |   +=v0010 -//	b015         | | +-+ -//	             | | | +=v0011 -//	b011         | +-+ -//	             |   |     +=v0015 -//	b027         |   |   +-+ -//	             |   |   | |     +=v0128 -//	b088         |   |   | |   +-+ -//	             |   |   | |   | +=v0192 -//	b058         |   |   | | +-+ -//	             |   |   | | | | +=v0026 -//	b089         |   |   | | | +-+ -//	             |   |   | | |   +=v0027 -//	b039         |   |   | +-+ -//	             |   |   |   |   +=v0028 -//	b090         |   |   |   | +-+ -//	             |   |   |   | | +=v0029 -//	b059         |   |   |   +-+ -//	             |   |   |     +=v0019 -//	b021         |   | +-+ -//	             |   | | |     +=v0020 -//	b060         |   | | |   +-+ -//	             |   | | |   | | +=v0034 -//	b091         |   | | |   | +-+ -//	             |   | | |   |   +=v0035 -//	b040         |   | | | +-+ -//	             |   | | | | |   +=v0036 -//	b092         |   | | | | | +-+ -//	             |   | | | | | | +=v0037 -//	b061         |   | | | | +-+ -//	             |   | | | |   | +=v0038 -//	b093         |   | | | |   +-+ -//	             |   | | | |     +=v0039 -//	b028         |   | | +-+ -//	             |   | |   |   +=v0021 -//	b062         |   | |   | +-+ -//	             |   | |   | | | +=v0042 -//	b094         |   | |   | | +-+ -//	             |   | |   | |   +=v0043 -//	b041         |   | |   +-+ -//	             |   | |     +=v0000 -//	b016         |   +-+ -//	             |     +=v0012 -//	b006       +-+ -//	           | |   +=v0009 -//	b012       | | +-+ -//	           | | | +=v0008 -//	b009       | +-+ -//	           |   +=v0007 -//	b004     +-+ -//	         | | +=v0006 -//	b007     | +-+ -//	         |   +=v0005 -//	b002   +-+ -//	       | | +=v0001 -//	b005   | +-+ -//	       |   +=v0004 -//	b001 +-+ -//	       | +=v0003 -//	b003   +-+ -//	         +=v0002 -var blackDecodeTable = [...][2]int16{ -	0:   {0, 0}, -	1:   {2, 3}, -	2:   {4, 5}, -	3:   {^3, ^2}, -	4:   {6, 7}, -	5:   {^1, ^4}, -	6:   {8, 9}, -	7:   {^6, ^5}, -	8:   {10, 11}, -	9:   {12, ^7}, -	10:  {13, 14}, -	11:  {15, 16}, -	12:  {^9, ^8}, -	13:  {17, 18}, -	14:  {19, 20}, -	15:  {^10, ^11}, -	16:  {21, ^12}, -	17:  {0, 22}, -	18:  {23, 24}, -	19:  {^13, 25}, -	20:  {26, ^14}, -	21:  {27, 28}, -	22:  {29, 30}, -	23:  {31, 32}, -	24:  {33, 34}, -	25:  {35, 36}, -	26:  {37, 38}, -	27:  {^15, 39}, -	28:  {40, 41}, -	29:  {42, 43}, -	30:  {44, 45}, -	31:  {^18, 46}, -	32:  {47, 48}, -	33:  {49, 50}, -	34:  {51, ^64}, -	35:  {52, 53}, -	36:  {54, ^16}, -	37:  {^17, 55}, -	38:  {56, 57}, -	39:  {58, 59}, -	40:  {60, 61}, -	41:  {62, ^0}, -	42:  {^1792, 63}, -	43:  {64, 65}, -	44:  {^1856, ^1920}, -	45:  {66, 67}, -	46:  {68, 69}, -	47:  {70, 71}, -	48:  {72, ^24}, -	49:  {^25, 73}, -	50:  {74, 75}, -	51:  {76, 77}, -	52:  {^23, 78}, -	53:  {79, 80}, -	54:  {81, 82}, -	55:  {83, 84}, -	56:  {85, 86}, -	57:  {87, ^22}, -	58:  {88, 89}, -	59:  {90, ^19}, -	60:  {^20, 91}, -	61:  {92, 93}, -	62:  {^21, 94}, -	63:  {^1984, ^2048}, -	64:  {^2112, ^2176}, -	65:  {^2240, ^2304}, -	66:  {^2368, ^2432}, -	67:  {^2496, ^2560}, -	68:  {^52, 95}, -	69:  {96, ^55}, -	70:  {^56, 97}, -	71:  {98, ^59}, -	72:  {^60, 99}, -	73:  {100, ^320}, -	74:  {^384, ^448}, -	75:  {101, ^53}, -	76:  {^54, 102}, -	77:  {103, 104}, -	78:  {^50, ^51}, -	79:  {^44, ^45}, -	80:  {^46, ^47}, -	81:  {^57, ^58}, -	82:  {^61, ^256}, -	83:  {^48, ^49}, -	84:  {^62, ^63}, -	85:  {^30, ^31}, -	86:  {^32, ^33}, -	87:  {^40, ^41}, -	88:  {^128, ^192}, -	89:  {^26, ^27}, -	90:  {^28, ^29}, -	91:  {^34, ^35}, -	92:  {^36, ^37}, -	93:  {^38, ^39}, -	94:  {^42, ^43}, -	95:  {^640, ^704}, -	96:  {^768, ^832}, -	97:  {^1280, ^1344}, -	98:  {^1408, ^1472}, -	99:  {^1536, ^1600}, -	100: {^1664, ^1728}, -	101: {^512, ^576}, -	102: {^896, ^960}, -	103: {^1024, ^1088}, -	104: {^1152, ^1216}, -} - -const maxCodeLength = 13 - -// Each encodeTable is represented by an array of bitStrings. - -// bitString is a pair of uint32 values representing a bit code. -// The nBits low bits of bits make up the actual bit code. -// Eg. bitString{0x0004, 8} represents the bitcode "00000100". -type bitString struct { -	bits  uint32 -	nBits uint32 -} - -// modeEncodeTable represents Table 1 and the End-of-Line code. -var modeEncodeTable = [...]bitString{ -	0: {0x0001, 4}, // "0001" -	1: {0x0001, 3}, // "001" -	2: {0x0001, 1}, // "1" -	3: {0x0003, 3}, // "011" -	4: {0x0003, 6}, // "000011" -	5: {0x0003, 7}, // "0000011" -	6: {0x0002, 3}, // "010" -	7: {0x0002, 6}, // "000010" -	8: {0x0002, 7}, // "0000010" -	9: {0x0001, 7}, // "0000001" -} - -// whiteEncodeTable2 represents Table 2 for a white run. -var whiteEncodeTable2 = [...]bitString{ -	0:  {0x0035, 8}, // "00110101" -	1:  {0x0007, 6}, // "000111" -	2:  {0x0007, 4}, // "0111" -	3:  {0x0008, 4}, // "1000" -	4:  {0x000b, 4}, // "1011" -	5:  {0x000c, 4}, // "1100" -	6:  {0x000e, 4}, // "1110" -	7:  {0x000f, 4}, // "1111" -	8:  {0x0013, 5}, // "10011" -	9:  {0x0014, 5}, // "10100" -	10: {0x0007, 5}, // "00111" -	11: {0x0008, 5}, // "01000" -	12: {0x0008, 6}, // "001000" -	13: {0x0003, 6}, // "000011" -	14: {0x0034, 6}, // "110100" -	15: {0x0035, 6}, // "110101" -	16: {0x002a, 6}, // "101010" -	17: {0x002b, 6}, // "101011" -	18: {0x0027, 7}, // "0100111" -	19: {0x000c, 7}, // "0001100" -	20: {0x0008, 7}, // "0001000" -	21: {0x0017, 7}, // "0010111" -	22: {0x0003, 7}, // "0000011" -	23: {0x0004, 7}, // "0000100" -	24: {0x0028, 7}, // "0101000" -	25: {0x002b, 7}, // "0101011" -	26: {0x0013, 7}, // "0010011" -	27: {0x0024, 7}, // "0100100" -	28: {0x0018, 7}, // "0011000" -	29: {0x0002, 8}, // "00000010" -	30: {0x0003, 8}, // "00000011" -	31: {0x001a, 8}, // "00011010" -	32: {0x001b, 8}, // "00011011" -	33: {0x0012, 8}, // "00010010" -	34: {0x0013, 8}, // "00010011" -	35: {0x0014, 8}, // "00010100" -	36: {0x0015, 8}, // "00010101" -	37: {0x0016, 8}, // "00010110" -	38: {0x0017, 8}, // "00010111" -	39: {0x0028, 8}, // "00101000" -	40: {0x0029, 8}, // "00101001" -	41: {0x002a, 8}, // "00101010" -	42: {0x002b, 8}, // "00101011" -	43: {0x002c, 8}, // "00101100" -	44: {0x002d, 8}, // "00101101" -	45: {0x0004, 8}, // "00000100" -	46: {0x0005, 8}, // "00000101" -	47: {0x000a, 8}, // "00001010" -	48: {0x000b, 8}, // "00001011" -	49: {0x0052, 8}, // "01010010" -	50: {0x0053, 8}, // "01010011" -	51: {0x0054, 8}, // "01010100" -	52: {0x0055, 8}, // "01010101" -	53: {0x0024, 8}, // "00100100" -	54: {0x0025, 8}, // "00100101" -	55: {0x0058, 8}, // "01011000" -	56: {0x0059, 8}, // "01011001" -	57: {0x005a, 8}, // "01011010" -	58: {0x005b, 8}, // "01011011" -	59: {0x004a, 8}, // "01001010" -	60: {0x004b, 8}, // "01001011" -	61: {0x0032, 8}, // "00110010" -	62: {0x0033, 8}, // "00110011" -	63: {0x0034, 8}, // "00110100" -} - -// whiteEncodeTable3 represents Table 3 for a white run. -var whiteEncodeTable3 = [...]bitString{ -	0:  {0x001b, 5},  // "11011" -	1:  {0x0012, 5},  // "10010" -	2:  {0x0017, 6},  // "010111" -	3:  {0x0037, 7},  // "0110111" -	4:  {0x0036, 8},  // "00110110" -	5:  {0x0037, 8},  // "00110111" -	6:  {0x0064, 8},  // "01100100" -	7:  {0x0065, 8},  // "01100101" -	8:  {0x0068, 8},  // "01101000" -	9:  {0x0067, 8},  // "01100111" -	10: {0x00cc, 9},  // "011001100" -	11: {0x00cd, 9},  // "011001101" -	12: {0x00d2, 9},  // "011010010" -	13: {0x00d3, 9},  // "011010011" -	14: {0x00d4, 9},  // "011010100" -	15: {0x00d5, 9},  // "011010101" -	16: {0x00d6, 9},  // "011010110" -	17: {0x00d7, 9},  // "011010111" -	18: {0x00d8, 9},  // "011011000" -	19: {0x00d9, 9},  // "011011001" -	20: {0x00da, 9},  // "011011010" -	21: {0x00db, 9},  // "011011011" -	22: {0x0098, 9},  // "010011000" -	23: {0x0099, 9},  // "010011001" -	24: {0x009a, 9},  // "010011010" -	25: {0x0018, 6},  // "011000" -	26: {0x009b, 9},  // "010011011" -	27: {0x0008, 11}, // "00000001000" -	28: {0x000c, 11}, // "00000001100" -	29: {0x000d, 11}, // "00000001101" -	30: {0x0012, 12}, // "000000010010" -	31: {0x0013, 12}, // "000000010011" -	32: {0x0014, 12}, // "000000010100" -	33: {0x0015, 12}, // "000000010101" -	34: {0x0016, 12}, // "000000010110" -	35: {0x0017, 12}, // "000000010111" -	36: {0x001c, 12}, // "000000011100" -	37: {0x001d, 12}, // "000000011101" -	38: {0x001e, 12}, // "000000011110" -	39: {0x001f, 12}, // "000000011111" -} - -// blackEncodeTable2 represents Table 2 for a black run. -var blackEncodeTable2 = [...]bitString{ -	0:  {0x0037, 10}, // "0000110111" -	1:  {0x0002, 3},  // "010" -	2:  {0x0003, 2},  // "11" -	3:  {0x0002, 2},  // "10" -	4:  {0x0003, 3},  // "011" -	5:  {0x0003, 4},  // "0011" -	6:  {0x0002, 4},  // "0010" -	7:  {0x0003, 5},  // "00011" -	8:  {0x0005, 6},  // "000101" -	9:  {0x0004, 6},  // "000100" -	10: {0x0004, 7},  // "0000100" -	11: {0x0005, 7},  // "0000101" -	12: {0x0007, 7},  // "0000111" -	13: {0x0004, 8},  // "00000100" -	14: {0x0007, 8},  // "00000111" -	15: {0x0018, 9},  // "000011000" -	16: {0x0017, 10}, // "0000010111" -	17: {0x0018, 10}, // "0000011000" -	18: {0x0008, 10}, // "0000001000" -	19: {0x0067, 11}, // "00001100111" -	20: {0x0068, 11}, // "00001101000" -	21: {0x006c, 11}, // "00001101100" -	22: {0x0037, 11}, // "00000110111" -	23: {0x0028, 11}, // "00000101000" -	24: {0x0017, 11}, // "00000010111" -	25: {0x0018, 11}, // "00000011000" -	26: {0x00ca, 12}, // "000011001010" -	27: {0x00cb, 12}, // "000011001011" -	28: {0x00cc, 12}, // "000011001100" -	29: {0x00cd, 12}, // "000011001101" -	30: {0x0068, 12}, // "000001101000" -	31: {0x0069, 12}, // "000001101001" -	32: {0x006a, 12}, // "000001101010" -	33: {0x006b, 12}, // "000001101011" -	34: {0x00d2, 12}, // "000011010010" -	35: {0x00d3, 12}, // "000011010011" -	36: {0x00d4, 12}, // "000011010100" -	37: {0x00d5, 12}, // "000011010101" -	38: {0x00d6, 12}, // "000011010110" -	39: {0x00d7, 12}, // "000011010111" -	40: {0x006c, 12}, // "000001101100" -	41: {0x006d, 12}, // "000001101101" -	42: {0x00da, 12}, // "000011011010" -	43: {0x00db, 12}, // "000011011011" -	44: {0x0054, 12}, // "000001010100" -	45: {0x0055, 12}, // "000001010101" -	46: {0x0056, 12}, // "000001010110" -	47: {0x0057, 12}, // "000001010111" -	48: {0x0064, 12}, // "000001100100" -	49: {0x0065, 12}, // "000001100101" -	50: {0x0052, 12}, // "000001010010" -	51: {0x0053, 12}, // "000001010011" -	52: {0x0024, 12}, // "000000100100" -	53: {0x0037, 12}, // "000000110111" -	54: {0x0038, 12}, // "000000111000" -	55: {0x0027, 12}, // "000000100111" -	56: {0x0028, 12}, // "000000101000" -	57: {0x0058, 12}, // "000001011000" -	58: {0x0059, 12}, // "000001011001" -	59: {0x002b, 12}, // "000000101011" -	60: {0x002c, 12}, // "000000101100" -	61: {0x005a, 12}, // "000001011010" -	62: {0x0066, 12}, // "000001100110" -	63: {0x0067, 12}, // "000001100111" -} - -// blackEncodeTable3 represents Table 3 for a black run. -var blackEncodeTable3 = [...]bitString{ -	0:  {0x000f, 10}, // "0000001111" -	1:  {0x00c8, 12}, // "000011001000" -	2:  {0x00c9, 12}, // "000011001001" -	3:  {0x005b, 12}, // "000001011011" -	4:  {0x0033, 12}, // "000000110011" -	5:  {0x0034, 12}, // "000000110100" -	6:  {0x0035, 12}, // "000000110101" -	7:  {0x006c, 13}, // "0000001101100" -	8:  {0x006d, 13}, // "0000001101101" -	9:  {0x004a, 13}, // "0000001001010" -	10: {0x004b, 13}, // "0000001001011" -	11: {0x004c, 13}, // "0000001001100" -	12: {0x004d, 13}, // "0000001001101" -	13: {0x0072, 13}, // "0000001110010" -	14: {0x0073, 13}, // "0000001110011" -	15: {0x0074, 13}, // "0000001110100" -	16: {0x0075, 13}, // "0000001110101" -	17: {0x0076, 13}, // "0000001110110" -	18: {0x0077, 13}, // "0000001110111" -	19: {0x0052, 13}, // "0000001010010" -	20: {0x0053, 13}, // "0000001010011" -	21: {0x0054, 13}, // "0000001010100" -	22: {0x0055, 13}, // "0000001010101" -	23: {0x005a, 13}, // "0000001011010" -	24: {0x005b, 13}, // "0000001011011" -	25: {0x0064, 13}, // "0000001100100" -	26: {0x0065, 13}, // "0000001100101" -	27: {0x0008, 11}, // "00000001000" -	28: {0x000c, 11}, // "00000001100" -	29: {0x000d, 11}, // "00000001101" -	30: {0x0012, 12}, // "000000010010" -	31: {0x0013, 12}, // "000000010011" -	32: {0x0014, 12}, // "000000010100" -	33: {0x0015, 12}, // "000000010101" -	34: {0x0016, 12}, // "000000010110" -	35: {0x0017, 12}, // "000000010111" -	36: {0x001c, 12}, // "000000011100" -	37: {0x001d, 12}, // "000000011101" -	38: {0x001e, 12}, // "000000011110" -	39: {0x001f, 12}, // "000000011111" -} - -// COPY PASTE table.go BEGIN - -const ( -	modePass = iota // Pass -	modeH           // Horizontal -	modeV0          // Vertical-0 -	modeVR1         // Vertical-Right-1 -	modeVR2         // Vertical-Right-2 -	modeVR3         // Vertical-Right-3 -	modeVL1         // Vertical-Left-1 -	modeVL2         // Vertical-Left-2 -	modeVL3         // Vertical-Left-3 -	modeExt         // Extension -) - -// COPY PASTE table.go END diff --git a/vendor/golang.org/x/image/ccitt/writer.go b/vendor/golang.org/x/image/ccitt/writer.go deleted file mode 100644 index 87130ab04..000000000 --- a/vendor/golang.org/x/image/ccitt/writer.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ccitt - -import ( -	"encoding/binary" -	"io" -) - -type bitWriter struct { -	w io.Writer - -	// order is whether to process w's bytes LSB first or MSB first. -	order Order - -	// The high nBits bits of the bits field hold encoded bits to be written to w. -	bits  uint64 -	nBits uint32 - -	// bytes[:bw] holds encoded bytes not yet written to w. -	// Overflow protection is ensured by using a multiple of 8 as bytes length. -	bw    uint32 -	bytes [1024]uint8 -} - -// flushBits copies 64 bits from b.bits to b.bytes. If b.bytes is then full, it -// is written to b.w. -func (b *bitWriter) flushBits() error { -	binary.BigEndian.PutUint64(b.bytes[b.bw:], b.bits) -	b.bits = 0 -	b.nBits = 0 -	b.bw += 8 -	if b.bw < uint32(len(b.bytes)) { -		return nil -	} -	b.bw = 0 -	if b.order != MSB { -		reverseBitsWithinBytes(b.bytes[:]) -	} -	_, err := b.w.Write(b.bytes[:]) -	return err -} - -// close finalizes a bitcode stream by writing any -// pending bits to bitWriter's underlying io.Writer. -func (b *bitWriter) close() error { -	// Write any encoded bits to bytes. -	if b.nBits > 0 { -		binary.BigEndian.PutUint64(b.bytes[b.bw:], b.bits) -		b.bw += (b.nBits + 7) >> 3 -	} - -	if b.order != MSB { -		reverseBitsWithinBytes(b.bytes[:b.bw]) -	} - -	// Write b.bw bytes to b.w. -	_, err := b.w.Write(b.bytes[:b.bw]) -	return err -} - -// alignToByteBoundary rounds b.nBits up to a multiple of 8. -// If all 64 bits are used, flush them to bitWriter's bytes. -func (b *bitWriter) alignToByteBoundary() error { -	if b.nBits = (b.nBits + 7) &^ 7; b.nBits == 64 { -		return b.flushBits() -	} -	return nil -} - -// writeCode writes a variable length bitcode to b's underlying io.Writer. -func (b *bitWriter) writeCode(bs bitString) error { -	bits := bs.bits -	nBits := bs.nBits -	if 64-b.nBits >= nBits { -		// b.bits has sufficient room for storing nBits bits. -		b.bits |= uint64(bits) << (64 - nBits - b.nBits) -		b.nBits += nBits -		if b.nBits == 64 { -			return b.flushBits() -		} -		return nil -	} - -	// Number of leading bits that fill b.bits. -	i := 64 - b.nBits - -	// Fill b.bits then flush and write remaining bits. -	b.bits |= uint64(bits) >> (nBits - i) -	b.nBits = 64 - -	if err := b.flushBits(); err != nil { -		return err -	} - -	nBits -= i -	b.bits = uint64(bits) << (64 - nBits) -	b.nBits = nBits -	return nil -} diff --git a/vendor/golang.org/x/image/tiff/buffer.go b/vendor/golang.org/x/image/tiff/buffer.go deleted file mode 100644 index d1801be48..000000000 --- a/vendor/golang.org/x/image/tiff/buffer.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tiff - -import "io" - -// buffer buffers an io.Reader to satisfy io.ReaderAt. -type buffer struct { -	r   io.Reader -	buf []byte -} - -// fill reads data from b.r until the buffer contains at least end bytes. -func (b *buffer) fill(end int) error { -	m := len(b.buf) -	if end > m { -		if end > cap(b.buf) { -			newcap := 1024 -			for newcap < end { -				newcap *= 2 -			} -			newbuf := make([]byte, end, newcap) -			copy(newbuf, b.buf) -			b.buf = newbuf -		} else { -			b.buf = b.buf[:end] -		} -		if n, err := io.ReadFull(b.r, b.buf[m:end]); err != nil { -			end = m + n -			b.buf = b.buf[:end] -			return err -		} -	} -	return nil -} - -func (b *buffer) ReadAt(p []byte, off int64) (int, error) { -	o := int(off) -	end := o + len(p) -	if int64(end) != off+int64(len(p)) { -		return 0, io.ErrUnexpectedEOF -	} - -	err := b.fill(end) -	return copy(p, b.buf[o:end]), err -} - -// Slice returns a slice of the underlying buffer. The slice contains -// n bytes starting at offset off. -func (b *buffer) Slice(off, n int) ([]byte, error) { -	end := off + n -	if err := b.fill(end); err != nil { -		return nil, err -	} -	return b.buf[off:end], nil -} - -// newReaderAt converts an io.Reader into an io.ReaderAt. -func newReaderAt(r io.Reader) io.ReaderAt { -	if ra, ok := r.(io.ReaderAt); ok { -		return ra -	} -	return &buffer{ -		r:   r, -		buf: make([]byte, 0, 1024), -	} -} diff --git a/vendor/golang.org/x/image/tiff/compress.go b/vendor/golang.org/x/image/tiff/compress.go deleted file mode 100644 index 3f176f00a..000000000 --- a/vendor/golang.org/x/image/tiff/compress.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tiff - -import ( -	"bufio" -	"io" -) - -type byteReader interface { -	io.Reader -	io.ByteReader -} - -// unpackBits decodes the PackBits-compressed data in src and returns the -// uncompressed data. -// -// The PackBits compression format is described in section 9 (p. 42) -// of the TIFF spec. -func unpackBits(r io.Reader) ([]byte, error) { -	buf := make([]byte, 128) -	dst := make([]byte, 0, 1024) -	br, ok := r.(byteReader) -	if !ok { -		br = bufio.NewReader(r) -	} - -	for { -		b, err := br.ReadByte() -		if err != nil { -			if err == io.EOF { -				return dst, nil -			} -			return nil, err -		} -		code := int(int8(b)) -		switch { -		case code >= 0: -			n, err := io.ReadFull(br, buf[:code+1]) -			if err != nil { -				return nil, err -			} -			dst = append(dst, buf[:n]...) -		case code == -128: -			// No-op. -		default: -			if b, err = br.ReadByte(); err != nil { -				return nil, err -			} -			for j := 0; j < 1-code; j++ { -				buf[j] = b -			} -			dst = append(dst, buf[:1-code]...) -		} -	} -} diff --git a/vendor/golang.org/x/image/tiff/consts.go b/vendor/golang.org/x/image/tiff/consts.go deleted file mode 100644 index 3e5f7f14d..000000000 --- a/vendor/golang.org/x/image/tiff/consts.go +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tiff - -// A tiff image file contains one or more images. The metadata -// of each image is contained in an Image File Directory (IFD), -// which contains entries of 12 bytes each and is described -// on page 14-16 of the specification. An IFD entry consists of -// -//  - a tag, which describes the signification of the entry, -//  - the data type and length of the entry, -//  - the data itself or a pointer to it if it is more than 4 bytes. -// -// The presence of a length means that each IFD is effectively an array. - -const ( -	leHeader = "II\x2A\x00" // Header for little-endian files. -	beHeader = "MM\x00\x2A" // Header for big-endian files. - -	ifdLen = 12 // Length of an IFD entry in bytes. -) - -// Data types (p. 14-16 of the spec). -const ( -	dtByte     = 1 -	dtASCII    = 2 -	dtShort    = 3 -	dtLong     = 4 -	dtRational = 5 -) - -// The length of one instance of each data type in bytes. -var lengths = [...]uint32{0, 1, 1, 2, 4, 8} - -// Tags (see p. 28-41 of the spec). -const ( -	tImageWidth                = 256 -	tImageLength               = 257 -	tBitsPerSample             = 258 -	tCompression               = 259 -	tPhotometricInterpretation = 262 - -	tFillOrder = 266 - -	tStripOffsets    = 273 -	tSamplesPerPixel = 277 -	tRowsPerStrip    = 278 -	tStripByteCounts = 279 - -	tT4Options = 292 // CCITT Group 3 options, a set of 32 flag bits. -	tT6Options = 293 // CCITT Group 4 options, a set of 32 flag bits. - -	tTileWidth      = 322 -	tTileLength     = 323 -	tTileOffsets    = 324 -	tTileByteCounts = 325 - -	tXResolution    = 282 -	tYResolution    = 283 -	tResolutionUnit = 296 - -	tPredictor    = 317 -	tColorMap     = 320 -	tExtraSamples = 338 -	tSampleFormat = 339 -) - -// Compression types (defined in various places in the spec and supplements). -const ( -	cNone       = 1 -	cCCITT      = 2 -	cG3         = 3 // Group 3 Fax. -	cG4         = 4 // Group 4 Fax. -	cLZW        = 5 -	cJPEGOld    = 6 // Superseded by cJPEG. -	cJPEG       = 7 -	cDeflate    = 8 // zlib compression. -	cPackBits   = 32773 -	cDeflateOld = 32946 // Superseded by cDeflate. -) - -// Photometric interpretation values (see p. 37 of the spec). -const ( -	pWhiteIsZero = 0 -	pBlackIsZero = 1 -	pRGB         = 2 -	pPaletted    = 3 -	pTransMask   = 4 // transparency mask -	pCMYK        = 5 -	pYCbCr       = 6 -	pCIELab      = 8 -) - -// Values for the tPredictor tag (page 64-65 of the spec). -const ( -	prNone       = 1 -	prHorizontal = 2 -) - -// Values for the tResolutionUnit tag (page 18). -const ( -	resNone    = 1 -	resPerInch = 2 // Dots per inch. -	resPerCM   = 3 // Dots per centimeter. -) - -// imageMode represents the mode of the image. -type imageMode int - -const ( -	mBilevel imageMode = iota -	mPaletted -	mGray -	mGrayInvert -	mRGB -	mRGBA -	mNRGBA -	mCMYK -) - -// CompressionType describes the type of compression used in Options. -type CompressionType int - -// Constants for supported compression types. -const ( -	Uncompressed CompressionType = iota -	Deflate -	LZW -	CCITTGroup3 -	CCITTGroup4 -) - -// specValue returns the compression type constant from the TIFF spec that -// is equivalent to c. -func (c CompressionType) specValue() uint32 { -	switch c { -	case LZW: -		return cLZW -	case Deflate: -		return cDeflate -	case CCITTGroup3: -		return cG3 -	case CCITTGroup4: -		return cG4 -	} -	return cNone -} diff --git a/vendor/golang.org/x/image/tiff/fuzz.go b/vendor/golang.org/x/image/tiff/fuzz.go deleted file mode 100644 index b388b6f42..000000000 --- a/vendor/golang.org/x/image/tiff/fuzz.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build gofuzz - -package tiff - -import "bytes" - -func Fuzz(data []byte) int { -	cfg, err := DecodeConfig(bytes.NewReader(data)) -	if err != nil { -		return 0 -	} -	if cfg.Width*cfg.Height > 1e6 { -		return 0 -	} -	img, err := Decode(bytes.NewReader(data)) -	if err != nil { -		return 0 -	} -	var w bytes.Buffer -	err = Encode(&w, img, nil) -	if err != nil { -		panic(err) -	} -	return 1 -} diff --git a/vendor/golang.org/x/image/tiff/lzw/reader.go b/vendor/golang.org/x/image/tiff/lzw/reader.go deleted file mode 100644 index 0aae475ab..000000000 --- a/vendor/golang.org/x/image/tiff/lzw/reader.go +++ /dev/null @@ -1,272 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package lzw implements the Lempel-Ziv-Welch compressed data format, -// described in T. A. Welch, “A Technique for High-Performance Data -// Compression”, Computer, 17(6) (June 1984), pp 8-19. -// -// In particular, it implements LZW as used by the TIFF file format, including -// an "off by one" algorithmic difference when compared to standard LZW. -package lzw // import "golang.org/x/image/tiff/lzw" - -/* -This file was branched from src/pkg/compress/lzw/reader.go in the -standard library. Differences from the original are marked with "NOTE". - -The tif_lzw.c file in the libtiff C library has this comment: - ----- -The 5.0 spec describes a different algorithm than Aldus -implements. Specifically, Aldus does code length transitions -one code earlier than should be done (for real LZW). -Earlier versions of this library implemented the correct -LZW algorithm, but emitted codes in a bit order opposite -to the TIFF spec. Thus, to maintain compatibility w/ Aldus -we interpret MSB-LSB ordered codes to be images written w/ -old versions of this library, but otherwise adhere to the -Aldus "off by one" algorithm. ----- - -The Go code doesn't read (invalid) TIFF files written by old versions of -libtiff, but the LZW algorithm in this package still differs from the one in -Go's standard package library to accommodate this "off by one" in valid TIFFs. -*/ - -import ( -	"bufio" -	"errors" -	"fmt" -	"io" -) - -// Order specifies the bit ordering in an LZW data stream. -type Order int - -const ( -	// LSB means Least Significant Bits first, as used in the GIF file format. -	LSB Order = iota -	// MSB means Most Significant Bits first, as used in the TIFF and PDF -	// file formats. -	MSB -) - -const ( -	maxWidth           = 12 -	decoderInvalidCode = 0xffff -	flushBuffer        = 1 << maxWidth -) - -// decoder is the state from which the readXxx method converts a byte -// stream into a code stream. -type decoder struct { -	r        io.ByteReader -	bits     uint32 -	nBits    uint -	width    uint -	read     func(*decoder) (uint16, error) // readLSB or readMSB -	litWidth int                            // width in bits of literal codes -	err      error - -	// The first 1<<litWidth codes are literal codes. -	// The next two codes mean clear and EOF. -	// Other valid codes are in the range [lo, hi] where lo := clear + 2, -	// with the upper bound incrementing on each code seen. -	// overflow is the code at which hi overflows the code width. NOTE: TIFF's LZW is "off by one". -	// last is the most recently seen code, or decoderInvalidCode. -	clear, eof, hi, overflow, last uint16 - -	// Each code c in [lo, hi] expands to two or more bytes. For c != hi: -	//   suffix[c] is the last of these bytes. -	//   prefix[c] is the code for all but the last byte. -	//   This code can either be a literal code or another code in [lo, c). -	// The c == hi case is a special case. -	suffix [1 << maxWidth]uint8 -	prefix [1 << maxWidth]uint16 - -	// output is the temporary output buffer. -	// Literal codes are accumulated from the start of the buffer. -	// Non-literal codes decode to a sequence of suffixes that are first -	// written right-to-left from the end of the buffer before being copied -	// to the start of the buffer. -	// It is flushed when it contains >= 1<<maxWidth bytes, -	// so that there is always room to decode an entire code. -	output [2 * 1 << maxWidth]byte -	o      int    // write index into output -	toRead []byte // bytes to return from Read -} - -// readLSB returns the next code for "Least Significant Bits first" data. -func (d *decoder) readLSB() (uint16, error) { -	for d.nBits < d.width { -		x, err := d.r.ReadByte() -		if err != nil { -			return 0, err -		} -		d.bits |= uint32(x) << d.nBits -		d.nBits += 8 -	} -	code := uint16(d.bits & (1<<d.width - 1)) -	d.bits >>= d.width -	d.nBits -= d.width -	return code, nil -} - -// readMSB returns the next code for "Most Significant Bits first" data. -func (d *decoder) readMSB() (uint16, error) { -	for d.nBits < d.width { -		x, err := d.r.ReadByte() -		if err != nil { -			return 0, err -		} -		d.bits |= uint32(x) << (24 - d.nBits) -		d.nBits += 8 -	} -	code := uint16(d.bits >> (32 - d.width)) -	d.bits <<= d.width -	d.nBits -= d.width -	return code, nil -} - -func (d *decoder) Read(b []byte) (int, error) { -	for { -		if len(d.toRead) > 0 { -			n := copy(b, d.toRead) -			d.toRead = d.toRead[n:] -			return n, nil -		} -		if d.err != nil { -			return 0, d.err -		} -		d.decode() -	} -} - -// decode decompresses bytes from r and leaves them in d.toRead. -// read specifies how to decode bytes into codes. -// litWidth is the width in bits of literal codes. -func (d *decoder) decode() { -	// Loop over the code stream, converting codes into decompressed bytes. -loop: -	for { -		code, err := d.read(d) -		if err != nil { -			if err == io.EOF { -				err = io.ErrUnexpectedEOF -			} -			d.err = err -			break -		} -		switch { -		case code < d.clear: -			// We have a literal code. -			d.output[d.o] = uint8(code) -			d.o++ -			if d.last != decoderInvalidCode { -				// Save what the hi code expands to. -				d.suffix[d.hi] = uint8(code) -				d.prefix[d.hi] = d.last -			} -		case code == d.clear: -			d.width = 1 + uint(d.litWidth) -			d.hi = d.eof -			d.overflow = 1 << d.width -			d.last = decoderInvalidCode -			continue -		case code == d.eof: -			d.err = io.EOF -			break loop -		case code <= d.hi: -			c, i := code, len(d.output)-1 -			if code == d.hi && d.last != decoderInvalidCode { -				// code == hi is a special case which expands to the last expansion -				// followed by the head of the last expansion. To find the head, we walk -				// the prefix chain until we find a literal code. -				c = d.last -				for c >= d.clear { -					c = d.prefix[c] -				} -				d.output[i] = uint8(c) -				i-- -				c = d.last -			} -			// Copy the suffix chain into output and then write that to w. -			for c >= d.clear { -				d.output[i] = d.suffix[c] -				i-- -				c = d.prefix[c] -			} -			d.output[i] = uint8(c) -			d.o += copy(d.output[d.o:], d.output[i:]) -			if d.last != decoderInvalidCode { -				// Save what the hi code expands to. -				d.suffix[d.hi] = uint8(c) -				d.prefix[d.hi] = d.last -			} -		default: -			d.err = errors.New("lzw: invalid code") -			break loop -		} -		d.last, d.hi = code, d.hi+1 -		if d.hi+1 >= d.overflow { // NOTE: the "+1" is where TIFF's LZW differs from the standard algorithm. -			if d.width == maxWidth { -				d.last = decoderInvalidCode -			} else { -				d.width++ -				d.overflow <<= 1 -			} -		} -		if d.o >= flushBuffer { -			break -		} -	} -	// Flush pending output. -	d.toRead = d.output[:d.o] -	d.o = 0 -} - -var errClosed = errors.New("lzw: reader/writer is closed") - -func (d *decoder) Close() error { -	d.err = errClosed // in case any Reads come along -	return nil -} - -// NewReader creates a new io.ReadCloser. -// Reads from the returned io.ReadCloser read and decompress data from r. -// If r does not also implement io.ByteReader, -// the decompressor may read more data than necessary from r. -// It is the caller's responsibility to call Close on the ReadCloser when -// finished reading. -// The number of bits to use for literal codes, litWidth, must be in the -// range [2,8] and is typically 8. It must equal the litWidth -// used during compression. -func NewReader(r io.Reader, order Order, litWidth int) io.ReadCloser { -	d := new(decoder) -	switch order { -	case LSB: -		d.read = (*decoder).readLSB -	case MSB: -		d.read = (*decoder).readMSB -	default: -		d.err = errors.New("lzw: unknown order") -		return d -	} -	if litWidth < 2 || 8 < litWidth { -		d.err = fmt.Errorf("lzw: litWidth %d out of range", litWidth) -		return d -	} -	if br, ok := r.(io.ByteReader); ok { -		d.r = br -	} else { -		d.r = bufio.NewReader(r) -	} -	d.litWidth = litWidth -	d.width = 1 + uint(litWidth) -	d.clear = uint16(1) << uint(litWidth) -	d.eof, d.hi = d.clear+1, d.clear+1 -	d.overflow = uint16(1) << d.width -	d.last = decoderInvalidCode - -	return d -} diff --git a/vendor/golang.org/x/image/tiff/reader.go b/vendor/golang.org/x/image/tiff/reader.go deleted file mode 100644 index 1b8fcb859..000000000 --- a/vendor/golang.org/x/image/tiff/reader.go +++ /dev/null @@ -1,785 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package tiff implements a TIFF image decoder and encoder. -// -// The TIFF specification is at http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf -package tiff // import "golang.org/x/image/tiff" - -import ( -	"bytes" -	"compress/zlib" -	"encoding/binary" -	"fmt" -	"image" -	"image/color" -	"io" -	"math" - -	"golang.org/x/image/ccitt" -	"golang.org/x/image/tiff/lzw" -) - -// A FormatError reports that the input is not a valid TIFF image. -type FormatError string - -func (e FormatError) Error() string { -	return "tiff: invalid format: " + string(e) -} - -// An UnsupportedError reports that the input uses a valid but -// unimplemented feature. -type UnsupportedError string - -func (e UnsupportedError) Error() string { -	return "tiff: unsupported feature: " + string(e) -} - -var ( -	errNoPixels          = FormatError("not enough pixel data") -	errInvalidColorIndex = FormatError("invalid color index") -) - -const maxChunkSize = 10 << 20 // 10M - -// safeReadAt is a verbatim copy of internal/saferio.ReadDataAt from the -// standard library, which is used to read data from a reader using a length -// provided by untrusted data, without allocating the entire slice ahead of time -// if it is large (>maxChunkSize). This allows us to avoid allocating giant -// slices before learning that we can't actually read that much data from the -// reader. -func safeReadAt(r io.ReaderAt, n uint64, off int64) ([]byte, error) { -	if int64(n) < 0 || n != uint64(int(n)) { -		// n is too large to fit in int, so we can't allocate -		// a buffer large enough. Treat this as a read failure. -		return nil, io.ErrUnexpectedEOF -	} - -	if n < maxChunkSize { -		buf := make([]byte, n) -		_, err := r.ReadAt(buf, off) -		if err != nil { -			// io.SectionReader can return EOF for n == 0, -			// but for our purposes that is a success. -			if err != io.EOF || n > 0 { -				return nil, err -			} -		} -		return buf, nil -	} - -	var buf []byte -	buf1 := make([]byte, maxChunkSize) -	for n > 0 { -		next := n -		if next > maxChunkSize { -			next = maxChunkSize -		} -		_, err := r.ReadAt(buf1[:next], off) -		if err != nil { -			return nil, err -		} -		buf = append(buf, buf1[:next]...) -		n -= next -		off += int64(next) -	} -	return buf, nil -} - -type decoder struct { -	r         io.ReaderAt -	byteOrder binary.ByteOrder -	config    image.Config -	mode      imageMode -	bpp       uint -	features  map[int][]uint -	palette   []color.Color - -	buf   []byte -	off   int    // Current offset in buf. -	v     uint32 // Buffer value for reading with arbitrary bit depths. -	nbits uint   // Remaining number of bits in v. -} - -// firstVal returns the first uint of the features entry with the given tag, -// or 0 if the tag does not exist. -func (d *decoder) firstVal(tag int) uint { -	f := d.features[tag] -	if len(f) == 0 { -		return 0 -	} -	return f[0] -} - -// ifdUint decodes the IFD entry in p, which must be of the Byte, Short -// or Long type, and returns the decoded uint values. -func (d *decoder) ifdUint(p []byte) (u []uint, err error) { -	var raw []byte -	if len(p) < ifdLen { -		return nil, FormatError("bad IFD entry") -	} - -	datatype := d.byteOrder.Uint16(p[2:4]) -	if dt := int(datatype); dt <= 0 || dt >= len(lengths) { -		return nil, UnsupportedError("IFD entry datatype") -	} - -	count := d.byteOrder.Uint32(p[4:8]) -	if count > math.MaxInt32/lengths[datatype] { -		return nil, FormatError("IFD data too large") -	} -	if datalen := lengths[datatype] * count; datalen > 4 { -		// The IFD contains a pointer to the real value. -		raw, err = safeReadAt(d.r, uint64(datalen), int64(d.byteOrder.Uint32(p[8:12]))) -	} else { -		raw = p[8 : 8+datalen] -	} -	if err != nil { -		return nil, err -	} - -	u = make([]uint, count) -	switch datatype { -	case dtByte: -		for i := uint32(0); i < count; i++ { -			u[i] = uint(raw[i]) -		} -	case dtShort: -		for i := uint32(0); i < count; i++ { -			u[i] = uint(d.byteOrder.Uint16(raw[2*i : 2*(i+1)])) -		} -	case dtLong: -		for i := uint32(0); i < count; i++ { -			u[i] = uint(d.byteOrder.Uint32(raw[4*i : 4*(i+1)])) -		} -	default: -		return nil, UnsupportedError("data type") -	} -	return u, nil -} - -// parseIFD decides whether the IFD entry in p is "interesting" and -// stows away the data in the decoder. It returns the tag number of the -// entry and an error, if any. -func (d *decoder) parseIFD(p []byte) (int, error) { -	tag := d.byteOrder.Uint16(p[0:2]) -	switch tag { -	case tBitsPerSample, -		tExtraSamples, -		tPhotometricInterpretation, -		tCompression, -		tPredictor, -		tStripOffsets, -		tStripByteCounts, -		tRowsPerStrip, -		tTileWidth, -		tTileLength, -		tTileOffsets, -		tTileByteCounts, -		tImageLength, -		tImageWidth, -		tFillOrder, -		tT4Options, -		tT6Options: -		val, err := d.ifdUint(p) -		if err != nil { -			return 0, err -		} -		d.features[int(tag)] = val -	case tColorMap: -		val, err := d.ifdUint(p) -		if err != nil { -			return 0, err -		} -		numcolors := len(val) / 3 -		if len(val)%3 != 0 || numcolors <= 0 || numcolors > 256 { -			return 0, FormatError("bad ColorMap length") -		} -		d.palette = make([]color.Color, numcolors) -		for i := 0; i < numcolors; i++ { -			d.palette[i] = color.RGBA64{ -				uint16(val[i]), -				uint16(val[i+numcolors]), -				uint16(val[i+2*numcolors]), -				0xffff, -			} -		} -	case tSampleFormat: -		// Page 27 of the spec: If the SampleFormat is present and -		// the value is not 1 [= unsigned integer data], a Baseline -		// TIFF reader that cannot handle the SampleFormat value -		// must terminate the import process gracefully. -		val, err := d.ifdUint(p) -		if err != nil { -			return 0, err -		} -		for _, v := range val { -			if v != 1 { -				return 0, UnsupportedError("sample format") -			} -		} -	} -	return int(tag), nil -} - -// readBits reads n bits from the internal buffer starting at the current offset. -func (d *decoder) readBits(n uint) (v uint32, ok bool) { -	for d.nbits < n { -		d.v <<= 8 -		if d.off >= len(d.buf) { -			return 0, false -		} -		d.v |= uint32(d.buf[d.off]) -		d.off++ -		d.nbits += 8 -	} -	d.nbits -= n -	rv := d.v >> d.nbits -	d.v &^= rv << d.nbits -	return rv, true -} - -// flushBits discards the unread bits in the buffer used by readBits. -// It is used at the end of a line. -func (d *decoder) flushBits() { -	d.v = 0 -	d.nbits = 0 -} - -// minInt returns the smaller of x or y. -func minInt(a, b int) int { -	if a <= b { -		return a -	} -	return b -} - -// decode decodes the raw data of an image. -// It reads from d.buf and writes the strip or tile into dst. -func (d *decoder) decode(dst image.Image, xmin, ymin, xmax, ymax int) error { -	d.off = 0 - -	// Apply horizontal predictor if necessary. -	// In this case, p contains the color difference to the preceding pixel. -	// See page 64-65 of the spec. -	if d.firstVal(tPredictor) == prHorizontal { -		switch d.bpp { -		case 16: -			var off int -			n := 2 * len(d.features[tBitsPerSample]) // bytes per sample times samples per pixel -			for y := ymin; y < ymax; y++ { -				off += n -				for x := 0; x < (xmax-xmin-1)*n; x += 2 { -					if off+2 > len(d.buf) { -						return errNoPixels -					} -					v0 := d.byteOrder.Uint16(d.buf[off-n : off-n+2]) -					v1 := d.byteOrder.Uint16(d.buf[off : off+2]) -					d.byteOrder.PutUint16(d.buf[off:off+2], v1+v0) -					off += 2 -				} -			} -		case 8: -			var off int -			n := 1 * len(d.features[tBitsPerSample]) // bytes per sample times samples per pixel -			for y := ymin; y < ymax; y++ { -				off += n -				for x := 0; x < (xmax-xmin-1)*n; x++ { -					if off >= len(d.buf) { -						return errNoPixels -					} -					d.buf[off] += d.buf[off-n] -					off++ -				} -			} -		case 1: -			return UnsupportedError("horizontal predictor with 1 BitsPerSample") -		} -	} - -	rMaxX := minInt(xmax, dst.Bounds().Max.X) -	rMaxY := minInt(ymax, dst.Bounds().Max.Y) -	switch d.mode { -	case mGray, mGrayInvert: -		if d.bpp == 16 { -			img := dst.(*image.Gray16) -			for y := ymin; y < rMaxY; y++ { -				for x := xmin; x < rMaxX; x++ { -					if d.off+2 > len(d.buf) { -						return errNoPixels -					} -					v := d.byteOrder.Uint16(d.buf[d.off : d.off+2]) -					d.off += 2 -					if d.mode == mGrayInvert { -						v = 0xffff - v -					} -					img.SetGray16(x, y, color.Gray16{v}) -				} -				if rMaxX == img.Bounds().Max.X { -					d.off += 2 * (xmax - img.Bounds().Max.X) -				} -			} -		} else { -			img := dst.(*image.Gray) -			max := uint32((1 << d.bpp) - 1) -			for y := ymin; y < rMaxY; y++ { -				for x := xmin; x < rMaxX; x++ { -					v, ok := d.readBits(d.bpp) -					if !ok { -						return errNoPixels -					} -					v = v * 0xff / max -					if d.mode == mGrayInvert { -						v = 0xff - v -					} -					img.SetGray(x, y, color.Gray{uint8(v)}) -				} -				d.flushBits() -			} -		} -	case mPaletted: -		img := dst.(*image.Paletted) -		pLen := len(d.palette) -		for y := ymin; y < rMaxY; y++ { -			for x := xmin; x < rMaxX; x++ { -				v, ok := d.readBits(d.bpp) -				if !ok { -					return errNoPixels -				} -				idx := uint8(v) -				if int(idx) >= pLen { -					return errInvalidColorIndex -				} -				img.SetColorIndex(x, y, idx) -			} -			d.flushBits() -		} -	case mRGB: -		if d.bpp == 16 { -			img := dst.(*image.RGBA64) -			for y := ymin; y < rMaxY; y++ { -				for x := xmin; x < rMaxX; x++ { -					if d.off+6 > len(d.buf) { -						return errNoPixels -					} -					r := d.byteOrder.Uint16(d.buf[d.off+0 : d.off+2]) -					g := d.byteOrder.Uint16(d.buf[d.off+2 : d.off+4]) -					b := d.byteOrder.Uint16(d.buf[d.off+4 : d.off+6]) -					d.off += 6 -					img.SetRGBA64(x, y, color.RGBA64{r, g, b, 0xffff}) -				} -			} -		} else { -			img := dst.(*image.RGBA) -			for y := ymin; y < rMaxY; y++ { -				min := img.PixOffset(xmin, y) -				max := img.PixOffset(rMaxX, y) -				off := (y - ymin) * (xmax - xmin) * 3 -				for i := min; i < max; i += 4 { -					if off+3 > len(d.buf) { -						return errNoPixels -					} -					img.Pix[i+0] = d.buf[off+0] -					img.Pix[i+1] = d.buf[off+1] -					img.Pix[i+2] = d.buf[off+2] -					img.Pix[i+3] = 0xff -					off += 3 -				} -			} -		} -	case mNRGBA: -		if d.bpp == 16 { -			img := dst.(*image.NRGBA64) -			for y := ymin; y < rMaxY; y++ { -				for x := xmin; x < rMaxX; x++ { -					if d.off+8 > len(d.buf) { -						return errNoPixels -					} -					r := d.byteOrder.Uint16(d.buf[d.off+0 : d.off+2]) -					g := d.byteOrder.Uint16(d.buf[d.off+2 : d.off+4]) -					b := d.byteOrder.Uint16(d.buf[d.off+4 : d.off+6]) -					a := d.byteOrder.Uint16(d.buf[d.off+6 : d.off+8]) -					d.off += 8 -					img.SetNRGBA64(x, y, color.NRGBA64{r, g, b, a}) -				} -			} -		} else { -			img := dst.(*image.NRGBA) -			for y := ymin; y < rMaxY; y++ { -				min := img.PixOffset(xmin, y) -				max := img.PixOffset(rMaxX, y) -				i0, i1 := (y-ymin)*(xmax-xmin)*4, (y-ymin+1)*(xmax-xmin)*4 -				if i1 > len(d.buf) { -					return errNoPixels -				} -				copy(img.Pix[min:max], d.buf[i0:i1]) -			} -		} -	case mRGBA: -		if d.bpp == 16 { -			img := dst.(*image.RGBA64) -			for y := ymin; y < rMaxY; y++ { -				for x := xmin; x < rMaxX; x++ { -					if d.off+8 > len(d.buf) { -						return errNoPixels -					} -					r := d.byteOrder.Uint16(d.buf[d.off+0 : d.off+2]) -					g := d.byteOrder.Uint16(d.buf[d.off+2 : d.off+4]) -					b := d.byteOrder.Uint16(d.buf[d.off+4 : d.off+6]) -					a := d.byteOrder.Uint16(d.buf[d.off+6 : d.off+8]) -					d.off += 8 -					img.SetRGBA64(x, y, color.RGBA64{r, g, b, a}) -				} -			} -		} else { -			img := dst.(*image.RGBA) -			for y := ymin; y < rMaxY; y++ { -				min := img.PixOffset(xmin, y) -				max := img.PixOffset(rMaxX, y) -				i0, i1 := (y-ymin)*(xmax-xmin)*4, (y-ymin+1)*(xmax-xmin)*4 -				if i1 > len(d.buf) { -					return errNoPixels -				} -				copy(img.Pix[min:max], d.buf[i0:i1]) -			} -		} -	} - -	return nil -} - -func newDecoder(r io.Reader) (*decoder, error) { -	d := &decoder{ -		r:        newReaderAt(r), -		features: make(map[int][]uint), -	} - -	p := make([]byte, 8) -	if _, err := d.r.ReadAt(p, 0); err != nil { -		if err == io.EOF { -			err = io.ErrUnexpectedEOF -		} -		return nil, err -	} -	switch string(p[0:4]) { -	case leHeader: -		d.byteOrder = binary.LittleEndian -	case beHeader: -		d.byteOrder = binary.BigEndian -	default: -		return nil, FormatError("malformed header") -	} - -	ifdOffset := int64(d.byteOrder.Uint32(p[4:8])) - -	// The first two bytes contain the number of entries (12 bytes each). -	if _, err := d.r.ReadAt(p[0:2], ifdOffset); err != nil { -		return nil, err -	} -	numItems := int(d.byteOrder.Uint16(p[0:2])) - -	// All IFD entries are read in one chunk. -	var err error -	p, err = safeReadAt(d.r, uint64(ifdLen*numItems), ifdOffset+2) -	if err != nil { -		return nil, err -	} - -	prevTag := -1 -	for i := 0; i < len(p); i += ifdLen { -		tag, err := d.parseIFD(p[i : i+ifdLen]) -		if err != nil { -			return nil, err -		} -		if tag <= prevTag { -			return nil, FormatError("tags are not sorted in ascending order") -		} -		prevTag = tag -	} - -	d.config.Width = int(d.firstVal(tImageWidth)) -	d.config.Height = int(d.firstVal(tImageLength)) - -	if _, ok := d.features[tBitsPerSample]; !ok { -		// Default is 1 per specification. -		d.features[tBitsPerSample] = []uint{1} -	} -	d.bpp = d.firstVal(tBitsPerSample) -	switch d.bpp { -	case 0: -		return nil, FormatError("BitsPerSample must not be 0") -	case 1, 8, 16: -		// Nothing to do, these are accepted by this implementation. -	default: -		return nil, UnsupportedError(fmt.Sprintf("BitsPerSample of %v", d.bpp)) -	} - -	// Determine the image mode. -	switch d.firstVal(tPhotometricInterpretation) { -	case pRGB: -		if d.bpp == 16 { -			for _, b := range d.features[tBitsPerSample] { -				if b != 16 { -					return nil, FormatError("wrong number of samples for 16bit RGB") -				} -			} -		} else { -			for _, b := range d.features[tBitsPerSample] { -				if b != 8 { -					return nil, FormatError("wrong number of samples for 8bit RGB") -				} -			} -		} -		// RGB images normally have 3 samples per pixel. -		// If there are more, ExtraSamples (p. 31-32 of the spec) -		// gives their meaning (usually an alpha channel). -		// -		// This implementation does not support extra samples -		// of an unspecified type. -		switch len(d.features[tBitsPerSample]) { -		case 3: -			d.mode = mRGB -			if d.bpp == 16 { -				d.config.ColorModel = color.RGBA64Model -			} else { -				d.config.ColorModel = color.RGBAModel -			} -		case 4: -			switch d.firstVal(tExtraSamples) { -			case 1: -				d.mode = mRGBA -				if d.bpp == 16 { -					d.config.ColorModel = color.RGBA64Model -				} else { -					d.config.ColorModel = color.RGBAModel -				} -			case 2: -				d.mode = mNRGBA -				if d.bpp == 16 { -					d.config.ColorModel = color.NRGBA64Model -				} else { -					d.config.ColorModel = color.NRGBAModel -				} -			default: -				return nil, FormatError("wrong number of samples for RGB") -			} -		default: -			return nil, FormatError("wrong number of samples for RGB") -		} -	case pPaletted: -		d.mode = mPaletted -		d.config.ColorModel = color.Palette(d.palette) -	case pWhiteIsZero: -		d.mode = mGrayInvert -		if d.bpp == 16 { -			d.config.ColorModel = color.Gray16Model -		} else { -			d.config.ColorModel = color.GrayModel -		} -	case pBlackIsZero: -		d.mode = mGray -		if d.bpp == 16 { -			d.config.ColorModel = color.Gray16Model -		} else { -			d.config.ColorModel = color.GrayModel -		} -	default: -		return nil, UnsupportedError("color model") -	} -	if d.firstVal(tPhotometricInterpretation) != pRGB { -		if len(d.features[tBitsPerSample]) != 1 { -			return nil, UnsupportedError("extra samples") -		} -	} - -	return d, nil -} - -// DecodeConfig returns the color model and dimensions of a TIFF image without -// decoding the entire image. -func DecodeConfig(r io.Reader) (image.Config, error) { -	d, err := newDecoder(r) -	if err != nil { -		return image.Config{}, err -	} -	return d.config, nil -} - -func ccittFillOrder(tiffFillOrder uint) ccitt.Order { -	if tiffFillOrder == 2 { -		return ccitt.LSB -	} -	return ccitt.MSB -} - -// Decode reads a TIFF image from r and returns it as an image.Image. -// The type of Image returned depends on the contents of the TIFF. -func Decode(r io.Reader) (img image.Image, err error) { -	d, err := newDecoder(r) -	if err != nil { -		return -	} - -	blockPadding := false -	blockWidth := d.config.Width -	blockHeight := d.config.Height -	blocksAcross := 1 -	blocksDown := 1 - -	if d.config.Width == 0 { -		blocksAcross = 0 -	} -	if d.config.Height == 0 { -		blocksDown = 0 -	} - -	var blockOffsets, blockCounts []uint - -	if int(d.firstVal(tTileWidth)) != 0 { -		blockPadding = true - -		blockWidth = int(d.firstVal(tTileWidth)) -		blockHeight = int(d.firstVal(tTileLength)) - -		// The specification says that tile widths and lengths must be a multiple of 16. -		// We currently permit invalid sizes, but reject anything too small to limit the -		// amount of work a malicious input can force us to perform. -		if blockWidth < 8 || blockHeight < 8 { -			return nil, FormatError("tile size is too small") -		} - -		if blockWidth != 0 { -			blocksAcross = (d.config.Width + blockWidth - 1) / blockWidth -		} -		if blockHeight != 0 { -			blocksDown = (d.config.Height + blockHeight - 1) / blockHeight -		} - -		blockCounts = d.features[tTileByteCounts] -		blockOffsets = d.features[tTileOffsets] - -	} else { -		if int(d.firstVal(tRowsPerStrip)) != 0 { -			blockHeight = int(d.firstVal(tRowsPerStrip)) -		} - -		if blockHeight != 0 { -			blocksDown = (d.config.Height + blockHeight - 1) / blockHeight -		} - -		blockOffsets = d.features[tStripOffsets] -		blockCounts = d.features[tStripByteCounts] -	} - -	// Check if we have the right number of strips/tiles, offsets and counts. -	if n := blocksAcross * blocksDown; len(blockOffsets) < n || len(blockCounts) < n { -		return nil, FormatError("inconsistent header") -	} - -	imgRect := image.Rect(0, 0, d.config.Width, d.config.Height) -	switch d.mode { -	case mGray, mGrayInvert: -		if d.bpp == 16 { -			img = image.NewGray16(imgRect) -		} else { -			img = image.NewGray(imgRect) -		} -	case mPaletted: -		img = image.NewPaletted(imgRect, d.palette) -	case mNRGBA: -		if d.bpp == 16 { -			img = image.NewNRGBA64(imgRect) -		} else { -			img = image.NewNRGBA(imgRect) -		} -	case mRGB, mRGBA: -		if d.bpp == 16 { -			img = image.NewRGBA64(imgRect) -		} else { -			img = image.NewRGBA(imgRect) -		} -	} - -	if blocksAcross == 0 || blocksDown == 0 { -		return -	} -	// Maximum data per pixel is 8 bytes (RGBA64). -	blockMaxDataSize := int64(blockWidth) * int64(blockHeight) * 8 -	for i := 0; i < blocksAcross; i++ { -		blkW := blockWidth -		if !blockPadding && i == blocksAcross-1 && d.config.Width%blockWidth != 0 { -			blkW = d.config.Width % blockWidth -		} -		for j := 0; j < blocksDown; j++ { -			blkH := blockHeight -			if !blockPadding && j == blocksDown-1 && d.config.Height%blockHeight != 0 { -				blkH = d.config.Height % blockHeight -			} -			offset := int64(blockOffsets[j*blocksAcross+i]) -			n := int64(blockCounts[j*blocksAcross+i]) -			switch d.firstVal(tCompression) { - -			// According to the spec, Compression does not have a default value, -			// but some tools interpret a missing Compression value as none so we do -			// the same. -			case cNone, 0: -				if b, ok := d.r.(*buffer); ok { -					d.buf, err = b.Slice(int(offset), int(n)) -				} else { -					d.buf, err = safeReadAt(d.r, uint64(n), offset) -				} -			case cG3: -				inv := d.firstVal(tPhotometricInterpretation) == pWhiteIsZero -				order := ccittFillOrder(d.firstVal(tFillOrder)) -				r := ccitt.NewReader(io.NewSectionReader(d.r, offset, n), order, ccitt.Group3, blkW, blkH, &ccitt.Options{Invert: inv, Align: false}) -				d.buf, err = readBuf(r, d.buf, blockMaxDataSize) -			case cG4: -				inv := d.firstVal(tPhotometricInterpretation) == pWhiteIsZero -				order := ccittFillOrder(d.firstVal(tFillOrder)) -				r := ccitt.NewReader(io.NewSectionReader(d.r, offset, n), order, ccitt.Group4, blkW, blkH, &ccitt.Options{Invert: inv, Align: false}) -				d.buf, err = readBuf(r, d.buf, blockMaxDataSize) -			case cLZW: -				r := lzw.NewReader(io.NewSectionReader(d.r, offset, n), lzw.MSB, 8) -				d.buf, err = readBuf(r, d.buf, blockMaxDataSize) -				r.Close() -			case cDeflate, cDeflateOld: -				var r io.ReadCloser -				r, err = zlib.NewReader(io.NewSectionReader(d.r, offset, n)) -				if err != nil { -					return nil, err -				} -				d.buf, err = readBuf(r, d.buf, blockMaxDataSize) -				r.Close() -			case cPackBits: -				d.buf, err = unpackBits(io.NewSectionReader(d.r, offset, n)) -			default: -				err = UnsupportedError(fmt.Sprintf("compression value %d", d.firstVal(tCompression))) -			} -			if err != nil { -				return nil, err -			} - -			xmin := i * blockWidth -			ymin := j * blockHeight -			xmax := xmin + blkW -			ymax := ymin + blkH -			err = d.decode(img, xmin, ymin, xmax, ymax) -			if err != nil { -				return nil, err -			} -		} -	} -	return -} - -func readBuf(r io.Reader, buf []byte, lim int64) ([]byte, error) { -	b := bytes.NewBuffer(buf[:0]) -	_, err := b.ReadFrom(io.LimitReader(r, lim)) -	return b.Bytes(), err -} - -func init() { -	image.RegisterFormat("tiff", leHeader, Decode, DecodeConfig) -	image.RegisterFormat("tiff", beHeader, Decode, DecodeConfig) -} diff --git a/vendor/golang.org/x/image/tiff/writer.go b/vendor/golang.org/x/image/tiff/writer.go deleted file mode 100644 index 5d461841c..000000000 --- a/vendor/golang.org/x/image/tiff/writer.go +++ /dev/null @@ -1,441 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package tiff - -import ( -	"bytes" -	"compress/zlib" -	"encoding/binary" -	"errors" -	"image" -	"io" -	"sort" -) - -// The TIFF format allows to choose the order of the different elements freely. -// The basic structure of a TIFF file written by this package is: -// -//   1. Header (8 bytes). -//   2. Image data. -//   3. Image File Directory (IFD). -//   4. "Pointer area" for larger entries in the IFD. - -// We only write little-endian TIFF files. -var enc = binary.LittleEndian - -// An ifdEntry is a single entry in an Image File Directory. -// A value of type dtRational is composed of two 32-bit values, -// thus data contains two uints (numerator and denominator) for a single number. -type ifdEntry struct { -	tag      int -	datatype int -	data     []uint32 -} - -func (e ifdEntry) putData(p []byte) { -	for _, d := range e.data { -		switch e.datatype { -		case dtByte, dtASCII: -			p[0] = byte(d) -			p = p[1:] -		case dtShort: -			enc.PutUint16(p, uint16(d)) -			p = p[2:] -		case dtLong, dtRational: -			enc.PutUint32(p, uint32(d)) -			p = p[4:] -		} -	} -} - -type byTag []ifdEntry - -func (d byTag) Len() int           { return len(d) } -func (d byTag) Less(i, j int) bool { return d[i].tag < d[j].tag } -func (d byTag) Swap(i, j int)      { d[i], d[j] = d[j], d[i] } - -func encodeGray(w io.Writer, pix []uint8, dx, dy, stride int, predictor bool) error { -	if !predictor { -		return writePix(w, pix, dy, dx, stride) -	} -	buf := make([]byte, dx) -	for y := 0; y < dy; y++ { -		min := y*stride + 0 -		max := y*stride + dx -		off := 0 -		var v0 uint8 -		for i := min; i < max; i++ { -			v1 := pix[i] -			buf[off] = v1 - v0 -			v0 = v1 -			off++ -		} -		if _, err := w.Write(buf); err != nil { -			return err -		} -	} -	return nil -} - -func encodeGray16(w io.Writer, pix []uint8, dx, dy, stride int, predictor bool) error { -	buf := make([]byte, dx*2) -	for y := 0; y < dy; y++ { -		min := y*stride + 0 -		max := y*stride + dx*2 -		off := 0 -		var v0 uint16 -		for i := min; i < max; i += 2 { -			// An image.Gray16's Pix is in big-endian order. -			v1 := uint16(pix[i])<<8 | uint16(pix[i+1]) -			if predictor { -				v0, v1 = v1, v1-v0 -			} -			// We only write little-endian TIFF files. -			buf[off+0] = byte(v1) -			buf[off+1] = byte(v1 >> 8) -			off += 2 -		} -		if _, err := w.Write(buf); err != nil { -			return err -		} -	} -	return nil -} - -func encodeRGBA(w io.Writer, pix []uint8, dx, dy, stride int, predictor bool) error { -	if !predictor { -		return writePix(w, pix, dy, dx*4, stride) -	} -	buf := make([]byte, dx*4) -	for y := 0; y < dy; y++ { -		min := y*stride + 0 -		max := y*stride + dx*4 -		off := 0 -		var r0, g0, b0, a0 uint8 -		for i := min; i < max; i += 4 { -			r1, g1, b1, a1 := pix[i+0], pix[i+1], pix[i+2], pix[i+3] -			buf[off+0] = r1 - r0 -			buf[off+1] = g1 - g0 -			buf[off+2] = b1 - b0 -			buf[off+3] = a1 - a0 -			off += 4 -			r0, g0, b0, a0 = r1, g1, b1, a1 -		} -		if _, err := w.Write(buf); err != nil { -			return err -		} -	} -	return nil -} - -func encodeRGBA64(w io.Writer, pix []uint8, dx, dy, stride int, predictor bool) error { -	buf := make([]byte, dx*8) -	for y := 0; y < dy; y++ { -		min := y*stride + 0 -		max := y*stride + dx*8 -		off := 0 -		var r0, g0, b0, a0 uint16 -		for i := min; i < max; i += 8 { -			// An image.RGBA64's Pix is in big-endian order. -			r1 := uint16(pix[i+0])<<8 | uint16(pix[i+1]) -			g1 := uint16(pix[i+2])<<8 | uint16(pix[i+3]) -			b1 := uint16(pix[i+4])<<8 | uint16(pix[i+5]) -			a1 := uint16(pix[i+6])<<8 | uint16(pix[i+7]) -			if predictor { -				r0, r1 = r1, r1-r0 -				g0, g1 = g1, g1-g0 -				b0, b1 = b1, b1-b0 -				a0, a1 = a1, a1-a0 -			} -			// We only write little-endian TIFF files. -			buf[off+0] = byte(r1) -			buf[off+1] = byte(r1 >> 8) -			buf[off+2] = byte(g1) -			buf[off+3] = byte(g1 >> 8) -			buf[off+4] = byte(b1) -			buf[off+5] = byte(b1 >> 8) -			buf[off+6] = byte(a1) -			buf[off+7] = byte(a1 >> 8) -			off += 8 -		} -		if _, err := w.Write(buf); err != nil { -			return err -		} -	} -	return nil -} - -func encode(w io.Writer, m image.Image, predictor bool) error { -	bounds := m.Bounds() -	buf := make([]byte, 4*bounds.Dx()) -	for y := bounds.Min.Y; y < bounds.Max.Y; y++ { -		off := 0 -		if predictor { -			var r0, g0, b0, a0 uint8 -			for x := bounds.Min.X; x < bounds.Max.X; x++ { -				r, g, b, a := m.At(x, y).RGBA() -				r1 := uint8(r >> 8) -				g1 := uint8(g >> 8) -				b1 := uint8(b >> 8) -				a1 := uint8(a >> 8) -				buf[off+0] = r1 - r0 -				buf[off+1] = g1 - g0 -				buf[off+2] = b1 - b0 -				buf[off+3] = a1 - a0 -				off += 4 -				r0, g0, b0, a0 = r1, g1, b1, a1 -			} -		} else { -			for x := bounds.Min.X; x < bounds.Max.X; x++ { -				r, g, b, a := m.At(x, y).RGBA() -				buf[off+0] = uint8(r >> 8) -				buf[off+1] = uint8(g >> 8) -				buf[off+2] = uint8(b >> 8) -				buf[off+3] = uint8(a >> 8) -				off += 4 -			} -		} -		if _, err := w.Write(buf); err != nil { -			return err -		} -	} -	return nil -} - -// writePix writes the internal byte array of an image to w. It is less general -// but much faster then encode. writePix is used when pix directly -// corresponds to one of the TIFF image types. -func writePix(w io.Writer, pix []byte, nrows, length, stride int) error { -	if length == stride { -		_, err := w.Write(pix[:nrows*length]) -		return err -	} -	for ; nrows > 0; nrows-- { -		if _, err := w.Write(pix[:length]); err != nil { -			return err -		} -		pix = pix[stride:] -	} -	return nil -} - -func writeIFD(w io.Writer, ifdOffset int, d []ifdEntry) error { -	var buf [ifdLen]byte -	// Make space for "pointer area" containing IFD entry data -	// longer than 4 bytes. -	parea := make([]byte, 1024) -	pstart := ifdOffset + ifdLen*len(d) + 6 -	var o int // Current offset in parea. - -	// The IFD has to be written with the tags in ascending order. -	sort.Sort(byTag(d)) - -	// Write the number of entries in this IFD. -	if err := binary.Write(w, enc, uint16(len(d))); err != nil { -		return err -	} -	for _, ent := range d { -		enc.PutUint16(buf[0:2], uint16(ent.tag)) -		enc.PutUint16(buf[2:4], uint16(ent.datatype)) -		count := uint32(len(ent.data)) -		if ent.datatype == dtRational { -			count /= 2 -		} -		enc.PutUint32(buf[4:8], count) -		datalen := int(count * lengths[ent.datatype]) -		if datalen <= 4 { -			ent.putData(buf[8:12]) -		} else { -			if (o + datalen) > len(parea) { -				newlen := len(parea) + 1024 -				for (o + datalen) > newlen { -					newlen += 1024 -				} -				newarea := make([]byte, newlen) -				copy(newarea, parea) -				parea = newarea -			} -			ent.putData(parea[o : o+datalen]) -			enc.PutUint32(buf[8:12], uint32(pstart+o)) -			o += datalen -		} -		if _, err := w.Write(buf[:]); err != nil { -			return err -		} -	} -	// The IFD ends with the offset of the next IFD in the file, -	// or zero if it is the last one (page 14). -	if err := binary.Write(w, enc, uint32(0)); err != nil { -		return err -	} -	_, err := w.Write(parea[:o]) -	return err -} - -// Options are the encoding parameters. -type Options struct { -	// Compression is the type of compression used. -	Compression CompressionType -	// Predictor determines whether a differencing predictor is used; -	// if true, instead of each pixel's color, the color difference to the -	// preceding one is saved. This improves the compression for certain -	// types of images and compressors. For example, it works well for -	// photos with Deflate compression. -	Predictor bool -} - -// Encode writes the image m to w. opt determines the options used for -// encoding, such as the compression type. If opt is nil, an uncompressed -// image is written. -func Encode(w io.Writer, m image.Image, opt *Options) error { -	d := m.Bounds().Size() - -	compression := uint32(cNone) -	predictor := false -	if opt != nil { -		compression = opt.Compression.specValue() -		// The predictor field is only used with LZW. See page 64 of the spec. -		predictor = opt.Predictor && compression == cLZW -	} - -	_, err := io.WriteString(w, leHeader) -	if err != nil { -		return err -	} - -	// Compressed data is written into a buffer first, so that we -	// know the compressed size. -	var buf bytes.Buffer -	// dst holds the destination for the pixel data of the image -- -	// either w or a writer to buf. -	var dst io.Writer -	// imageLen is the length of the pixel data in bytes. -	// The offset of the IFD is imageLen + 8 header bytes. -	var imageLen int - -	switch compression { -	case cNone: -		dst = w -		// Write IFD offset before outputting pixel data. -		switch m.(type) { -		case *image.Paletted: -			imageLen = d.X * d.Y * 1 -		case *image.Gray: -			imageLen = d.X * d.Y * 1 -		case *image.Gray16: -			imageLen = d.X * d.Y * 2 -		case *image.RGBA64: -			imageLen = d.X * d.Y * 8 -		case *image.NRGBA64: -			imageLen = d.X * d.Y * 8 -		default: -			imageLen = d.X * d.Y * 4 -		} -		err = binary.Write(w, enc, uint32(imageLen+8)) -		if err != nil { -			return err -		} -	case cDeflate: -		dst = zlib.NewWriter(&buf) -	default: -		return errors.New("tiff: unsupported compression") -	} - -	pr := uint32(prNone) -	photometricInterpretation := uint32(pRGB) -	samplesPerPixel := uint32(4) -	bitsPerSample := []uint32{8, 8, 8, 8} -	extraSamples := uint32(0) -	colorMap := []uint32{} - -	if predictor { -		pr = prHorizontal -	} -	switch m := m.(type) { -	case *image.Paletted: -		photometricInterpretation = pPaletted -		samplesPerPixel = 1 -		bitsPerSample = []uint32{8} -		colorMap = make([]uint32, 256*3) -		for i := 0; i < 256 && i < len(m.Palette); i++ { -			r, g, b, _ := m.Palette[i].RGBA() -			colorMap[i+0*256] = uint32(r) -			colorMap[i+1*256] = uint32(g) -			colorMap[i+2*256] = uint32(b) -		} -		err = encodeGray(dst, m.Pix, d.X, d.Y, m.Stride, predictor) -	case *image.Gray: -		photometricInterpretation = pBlackIsZero -		samplesPerPixel = 1 -		bitsPerSample = []uint32{8} -		err = encodeGray(dst, m.Pix, d.X, d.Y, m.Stride, predictor) -	case *image.Gray16: -		photometricInterpretation = pBlackIsZero -		samplesPerPixel = 1 -		bitsPerSample = []uint32{16} -		err = encodeGray16(dst, m.Pix, d.X, d.Y, m.Stride, predictor) -	case *image.NRGBA: -		extraSamples = 2 // Unassociated alpha. -		err = encodeRGBA(dst, m.Pix, d.X, d.Y, m.Stride, predictor) -	case *image.NRGBA64: -		extraSamples = 2 // Unassociated alpha. -		bitsPerSample = []uint32{16, 16, 16, 16} -		err = encodeRGBA64(dst, m.Pix, d.X, d.Y, m.Stride, predictor) -	case *image.RGBA: -		extraSamples = 1 // Associated alpha. -		err = encodeRGBA(dst, m.Pix, d.X, d.Y, m.Stride, predictor) -	case *image.RGBA64: -		extraSamples = 1 // Associated alpha. -		bitsPerSample = []uint32{16, 16, 16, 16} -		err = encodeRGBA64(dst, m.Pix, d.X, d.Y, m.Stride, predictor) -	default: -		extraSamples = 1 // Associated alpha. -		err = encode(dst, m, predictor) -	} -	if err != nil { -		return err -	} - -	if compression != cNone { -		if err = dst.(io.Closer).Close(); err != nil { -			return err -		} -		imageLen = buf.Len() -		if err = binary.Write(w, enc, uint32(imageLen+8)); err != nil { -			return err -		} -		if _, err = buf.WriteTo(w); err != nil { -			return err -		} -	} - -	ifd := []ifdEntry{ -		{tImageWidth, dtShort, []uint32{uint32(d.X)}}, -		{tImageLength, dtShort, []uint32{uint32(d.Y)}}, -		{tBitsPerSample, dtShort, bitsPerSample}, -		{tCompression, dtShort, []uint32{compression}}, -		{tPhotometricInterpretation, dtShort, []uint32{photometricInterpretation}}, -		{tStripOffsets, dtLong, []uint32{8}}, -		{tSamplesPerPixel, dtShort, []uint32{samplesPerPixel}}, -		{tRowsPerStrip, dtShort, []uint32{uint32(d.Y)}}, -		{tStripByteCounts, dtLong, []uint32{uint32(imageLen)}}, -		// There is currently no support for storing the image -		// resolution, so give a bogus value of 72x72 dpi. -		{tXResolution, dtRational, []uint32{72, 1}}, -		{tYResolution, dtRational, []uint32{72, 1}}, -		{tResolutionUnit, dtShort, []uint32{resPerInch}}, -	} -	if pr != prNone { -		ifd = append(ifd, ifdEntry{tPredictor, dtShort, []uint32{pr}}) -	} -	if len(colorMap) != 0 { -		ifd = append(ifd, ifdEntry{tColorMap, dtShort, colorMap}) -	} -	if extraSamples > 0 { -		ifd = append(ifd, ifdEntry{tExtraSamples, dtShort, []uint32{extraSamples}}) -	} - -	return writeIFD(w, imageLen+8, ifd) -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 612d8a0f7..52a61a714 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -175,9 +175,6 @@ github.com/coreos/go-systemd/v22/dbus  # github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc  ## explicit  github.com/davecgh/go-spew/spew -# github.com/disintegration/imaging v1.6.2 -## explicit -github.com/disintegration/imaging  # github.com/docker/go-units v0.5.0  ## explicit  github.com/docker/go-units @@ -1095,11 +1092,7 @@ golang.org/x/exp/slog/internal  golang.org/x/exp/slog/internal/buffer  # golang.org/x/image v0.19.0  ## explicit; go 1.18 -golang.org/x/image/bmp -golang.org/x/image/ccitt  golang.org/x/image/riff -golang.org/x/image/tiff -golang.org/x/image/tiff/lzw  golang.org/x/image/vp8  golang.org/x/image/vp8l  golang.org/x/image/webp | 
