diff options
Diffstat (limited to 'vendor/github.com/disintegration/imaging/io.go')
-rw-r--r-- | vendor/github.com/disintegration/imaging/io.go | 444 |
1 files changed, 0 insertions, 444 deletions
diff --git a/vendor/github.com/disintegration/imaging/io.go b/vendor/github.com/disintegration/imaging/io.go deleted file mode 100644 index f6c6da86..00000000 --- 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 -} |