mirror of
https://github.com/imgproxy/imgproxy.git
synced 2024-11-24 08:12:38 +02:00
Use imagetype and config in imagemeta
This commit is contained in:
parent
2ea1466d96
commit
0af4720cfa
@ -8,7 +8,6 @@ import (
|
|||||||
"github.com/imgproxy/imgproxy/v2/config"
|
"github.com/imgproxy/imgproxy/v2/config"
|
||||||
"github.com/imgproxy/imgproxy/v2/ierrors"
|
"github.com/imgproxy/imgproxy/v2/ierrors"
|
||||||
"github.com/imgproxy/imgproxy/v2/imagemeta"
|
"github.com/imgproxy/imgproxy/v2/imagemeta"
|
||||||
"github.com/imgproxy/imgproxy/v2/imagetype"
|
|
||||||
"github.com/imgproxy/imgproxy/v2/security"
|
"github.com/imgproxy/imgproxy/v2/security"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,8 +20,6 @@ var downloadBufPool *bufpool.Pool
|
|||||||
|
|
||||||
func initRead() {
|
func initRead() {
|
||||||
downloadBufPool = bufpool.New("download", config.Concurrency, config.DownloadBufferSize)
|
downloadBufPool = bufpool.New("download", config.Concurrency, config.DownloadBufferSize)
|
||||||
|
|
||||||
imagemeta.SetMaxSvgCheckRead(config.MaxSvgCheckBytes)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type hardLimitReader struct {
|
type hardLimitReader struct {
|
||||||
@ -64,11 +61,6 @@ func readAndCheckImage(r io.Reader, contentLength int) (*ImageData, error) {
|
|||||||
return nil, ierrors.Wrap(err, 0)
|
return nil, ierrors.Wrap(err, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
imgtype, imgtypeOk := imagetype.Types[meta.Format()]
|
|
||||||
if !imgtypeOk {
|
|
||||||
return nil, ErrSourceImageTypeNotSupported
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = security.CheckDimensions(meta.Width(), meta.Height()); err != nil {
|
if err = security.CheckDimensions(meta.Width(), meta.Height()); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -80,7 +72,7 @@ func readAndCheckImage(r io.Reader, contentLength int) (*ImageData, error) {
|
|||||||
|
|
||||||
return &ImageData{
|
return &ImageData{
|
||||||
Data: buf.Bytes(),
|
Data: buf.Bytes(),
|
||||||
Type: imgtype,
|
Type: meta.Format(),
|
||||||
cancel: cancel,
|
cancel: cancel,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/imgproxy/imgproxy/v2/imagetype"
|
||||||
)
|
)
|
||||||
|
|
||||||
var bmpMagick = []byte("BM")
|
var bmpMagick = []byte("BM")
|
||||||
@ -37,7 +39,7 @@ func DecodeBmpMeta(r io.Reader) (Meta, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &meta{
|
return &meta{
|
||||||
format: "bmp",
|
format: imagetype.BMP,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -2,6 +2,8 @@ package imagemeta
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/imgproxy/imgproxy/v2/imagetype"
|
||||||
)
|
)
|
||||||
|
|
||||||
func DecodeGifMeta(r io.Reader) (Meta, error) {
|
func DecodeGifMeta(r io.Reader) (Meta, error) {
|
||||||
@ -13,7 +15,7 @@ func DecodeGifMeta(r io.Reader) (Meta, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &meta{
|
return &meta{
|
||||||
format: "gif",
|
format: imagetype.GIF,
|
||||||
width: int(tmp[6]) + int(tmp[7])<<8,
|
width: int(tmp[6]) + int(tmp[7])<<8,
|
||||||
height: int(tmp[8]) + int(tmp[9])<<8,
|
height: int(tmp[8]) + int(tmp[9])<<8,
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -7,6 +7,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
|
"github.com/imgproxy/imgproxy/v2/imagetype"
|
||||||
)
|
)
|
||||||
|
|
||||||
const heifBoxHeaderSize = int64(8)
|
const heifBoxHeaderSize = int64(8)
|
||||||
@ -20,12 +22,12 @@ type heifDiscarder interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type heifData struct {
|
type heifData struct {
|
||||||
Format string
|
Format imagetype.Type
|
||||||
Width, Height int64
|
Width, Height int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *heifData) IsFilled() bool {
|
func (d *heifData) IsFilled() bool {
|
||||||
return len(d.Format) > 0 && d.Width > 0 && d.Height > 0
|
return d.Format != imagetype.Unknown && d.Width > 0 && d.Height > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func heifReadN(r io.Reader, n int64) (b []byte, err error) {
|
func heifReadN(r io.Reader, n int64) (b []byte, err error) {
|
||||||
@ -73,12 +75,12 @@ func heifReadBoxHeader(r io.Reader) (boxType string, boxDataSize int64, err erro
|
|||||||
|
|
||||||
func heifAssignFormat(d *heifData, brand []byte) bool {
|
func heifAssignFormat(d *heifData, brand []byte) bool {
|
||||||
if bytes.Equal(brand, heicBrand) {
|
if bytes.Equal(brand, heicBrand) {
|
||||||
d.Format = "heic"
|
d.Format = imagetype.HEIC
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if bytes.Equal(brand, avifBrand) {
|
if bytes.Equal(brand, avifBrand) {
|
||||||
d.Format = "avif"
|
d.Format = imagetype.AVIF
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/imgproxy/imgproxy/v2/imagetype"
|
||||||
)
|
)
|
||||||
|
|
||||||
type IcoMeta struct {
|
type IcoMeta struct {
|
||||||
@ -69,7 +71,7 @@ func DecodeIcoMeta(r io.Reader) (*IcoMeta, error) {
|
|||||||
|
|
||||||
return &IcoMeta{
|
return &IcoMeta{
|
||||||
Meta: &meta{
|
Meta: &meta{
|
||||||
format: "ico",
|
format: imagetype.ICO,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
},
|
},
|
||||||
|
@ -6,10 +6,12 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
|
"github.com/imgproxy/imgproxy/v2/imagetype"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Meta interface {
|
type Meta interface {
|
||||||
Format() string
|
Format() imagetype.Type
|
||||||
Width() int
|
Width() int
|
||||||
Height() int
|
Height() int
|
||||||
}
|
}
|
||||||
@ -17,11 +19,11 @@ type Meta interface {
|
|||||||
type DecodeMetaFunc func(io.Reader) (Meta, error)
|
type DecodeMetaFunc func(io.Reader) (Meta, error)
|
||||||
|
|
||||||
type meta struct {
|
type meta struct {
|
||||||
format string
|
format imagetype.Type
|
||||||
width, height int
|
width, height int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *meta) Format() string {
|
func (m *meta) Format() imagetype.Type {
|
||||||
return m.format
|
return m.format
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +93,7 @@ func DecodeMeta(r io.Reader) (Meta, error) {
|
|||||||
if ok, err := IsSVG(rr); err != nil {
|
if ok, err := IsSVG(rr); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if ok {
|
} else if ok {
|
||||||
return &meta{format: "svg", width: 1, height: 1}, nil
|
return &meta{format: imagetype.SVG, width: 1, height: 1}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, ErrFormat
|
return nil, ErrFormat
|
||||||
|
@ -3,6 +3,8 @@ package imagemeta
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/imgproxy/imgproxy/v2/imagetype"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -101,7 +103,7 @@ func DecodeJpegMeta(rr io.Reader) (Meta, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &meta{
|
return &meta{
|
||||||
format: "jpeg",
|
format: imagetype.JPEG,
|
||||||
width: int(tmp[3])<<8 + int(tmp[4]),
|
width: int(tmp[3])<<8 + int(tmp[4]),
|
||||||
height: int(tmp[1])<<8 + int(tmp[2]),
|
height: int(tmp[1])<<8 + int(tmp[2]),
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -4,6 +4,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/imgproxy/imgproxy/v2/imagetype"
|
||||||
)
|
)
|
||||||
|
|
||||||
var pngMagick = []byte("\x89PNG\r\n\x1a\n")
|
var pngMagick = []byte("\x89PNG\r\n\x1a\n")
|
||||||
@ -28,7 +30,7 @@ func DecodePngMeta(r io.Reader) (Meta, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &meta{
|
return &meta{
|
||||||
format: "png",
|
format: imagetype.PNG,
|
||||||
width: int(binary.BigEndian.Uint32(tmp[8:12])),
|
width: int(binary.BigEndian.Uint32(tmp[8:12])),
|
||||||
height: int(binary.BigEndian.Uint32(tmp[12:16])),
|
height: int(binary.BigEndian.Uint32(tmp[12:16])),
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -6,13 +6,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
|
"github.com/imgproxy/imgproxy/v2/config"
|
||||||
"golang.org/x/text/encoding/charmap"
|
"golang.org/x/text/encoding/charmap"
|
||||||
)
|
)
|
||||||
|
|
||||||
var maxSvgBytes int64 = 32 * 1024
|
|
||||||
|
|
||||||
type svgHeader struct {
|
type svgHeader struct {
|
||||||
XMLName xml.Name
|
XMLName xml.Name
|
||||||
}
|
}
|
||||||
@ -24,12 +22,8 @@ func xmlCharsetReader(charset string, input io.Reader) (io.Reader, error) {
|
|||||||
return nil, fmt.Errorf("Unknown SVG charset: %s", charset)
|
return nil, fmt.Errorf("Unknown SVG charset: %s", charset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetMaxSvgCheckRead(n int) {
|
|
||||||
atomic.StoreInt64(&maxSvgBytes, int64(n))
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsSVG(r io.Reader) (bool, error) {
|
func IsSVG(r io.Reader) (bool, error) {
|
||||||
maxBytes := int(atomic.LoadInt64(&maxSvgBytes))
|
maxBytes := config.MaxSvgCheckBytes
|
||||||
|
|
||||||
var h svgHeader
|
var h svgHeader
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/imgproxy/imgproxy/v2/imagetype"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -105,7 +107,7 @@ func DecodeTiffMeta(rr io.Reader) (Meta, error) {
|
|||||||
|
|
||||||
if width > 0 && height > 0 {
|
if width > 0 && height > 0 {
|
||||||
return &meta{
|
return &meta{
|
||||||
format: "tiff",
|
format: imagetype.TIFF,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/imgproxy/imgproxy/v2/imagetype"
|
||||||
"golang.org/x/image/riff"
|
"golang.org/x/image/riff"
|
||||||
"golang.org/x/image/vp8"
|
"golang.org/x/image/vp8"
|
||||||
"golang.org/x/image/vp8l"
|
"golang.org/x/image/vp8l"
|
||||||
@ -59,7 +60,7 @@ func DecodeWebpMeta(r io.Reader) (Meta, error) {
|
|||||||
fh, err := d.DecodeFrameHeader()
|
fh, err := d.DecodeFrameHeader()
|
||||||
|
|
||||||
return &meta{
|
return &meta{
|
||||||
format: "webp",
|
format: imagetype.WEBP,
|
||||||
width: fh.Width,
|
width: fh.Width,
|
||||||
height: fh.Height,
|
height: fh.Height,
|
||||||
}, err
|
}, err
|
||||||
@ -71,7 +72,7 @@ func DecodeWebpMeta(r io.Reader) (Meta, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &meta{
|
return &meta{
|
||||||
format: "webp",
|
format: imagetype.WEBP,
|
||||||
width: conf.Width,
|
width: conf.Width,
|
||||||
height: conf.Height,
|
height: conf.Height,
|
||||||
}, nil
|
}, nil
|
||||||
@ -89,7 +90,7 @@ func DecodeWebpMeta(r io.Reader) (Meta, error) {
|
|||||||
heightMinusOne := uint32(buf[7]) | uint32(buf[8])<<8 | uint32(buf[9])<<16
|
heightMinusOne := uint32(buf[7]) | uint32(buf[8])<<8 | uint32(buf[9])<<16
|
||||||
|
|
||||||
return &meta{
|
return &meta{
|
||||||
format: "webp",
|
format: imagetype.WEBP,
|
||||||
width: int(widthMinusOne) + 1,
|
width: int(widthMinusOne) + 1,
|
||||||
height: int(heightMinusOne) + 1,
|
height: int(heightMinusOne) + 1,
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -90,7 +90,7 @@ func (s *ProcessingHandlerTestSuite) TestRequest() {
|
|||||||
meta, err := imagemeta.DecodeMeta(res.Body)
|
meta, err := imagemeta.DecodeMeta(res.Body)
|
||||||
|
|
||||||
assert.Nil(s.T(), err)
|
assert.Nil(s.T(), err)
|
||||||
assert.Equal(s.T(), "png", meta.Format())
|
assert.Equal(s.T(), imagetype.PNG, meta.Format())
|
||||||
assert.Equal(s.T(), 4, meta.Width())
|
assert.Equal(s.T(), 4, meta.Width())
|
||||||
assert.Equal(s.T(), 4, meta.Height())
|
assert.Equal(s.T(), 4, meta.Height())
|
||||||
}
|
}
|
||||||
|
11
vips/ico.go
11
vips/ico.go
@ -27,24 +27,23 @@ func (img *Image) loadIco(data []byte, shrink int, scale float64, pages int) err
|
|||||||
|
|
||||||
internalData := data[offset : offset+size]
|
internalData := data[offset : offset+size]
|
||||||
|
|
||||||
var format string
|
var internalType imagetype.Type
|
||||||
|
|
||||||
meta, err := imagemeta.DecodeMeta(bytes.NewReader(internalData))
|
meta, err := imagemeta.DecodeMeta(bytes.NewReader(internalData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Looks like it's BMP with an incomplete header
|
// Looks like it's BMP with an incomplete header
|
||||||
if d, err := imagemeta.FixBmpHeader(internalData); err == nil {
|
if d, err := imagemeta.FixBmpHeader(internalData); err == nil {
|
||||||
format = "bmp"
|
internalType = imagetype.BMP
|
||||||
internalData = d
|
internalData = d
|
||||||
} else {
|
} else {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
format = meta.Format()
|
internalType = meta.Format()
|
||||||
}
|
}
|
||||||
|
|
||||||
internalType, ok := imagetype.Types[format]
|
if internalType == imagetype.ICO || !SupportsLoad(internalType) {
|
||||||
if !ok || internalType == imagetype.ICO || !SupportsLoad(internalType) {
|
return fmt.Errorf("Can't load %s from ICO", internalType)
|
||||||
return fmt.Errorf("Can't load %s from ICO", meta.Format())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
imgdata := imagedata.ImageData{
|
imgdata := imagedata.ImageData{
|
||||||
|
Loading…
Reference in New Issue
Block a user