1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-06-22 22:37:41 +02:00

Refactor subpackages

This commit is contained in:
DarthSim
2019-12-25 15:06:15 +06:00
parent 8ce331d2ee
commit 7c7ac56a48
14 changed files with 123 additions and 79 deletions

View File

@ -10,7 +10,7 @@ import (
"net/http" "net/http"
"time" "time"
imagesize "github.com/imgproxy/imgproxy/image_size" "github.com/imgproxy/imgproxy/imagemeta"
) )
var ( var (
@ -102,20 +102,20 @@ func checkDimensions(width, height int) error {
} }
func checkTypeAndDimensions(r io.Reader) (imageType, error) { func checkTypeAndDimensions(r io.Reader) (imageType, error) {
meta, err := imagesize.DecodeMeta(r) meta, err := imagemeta.DecodeMeta(r)
if err == imagesize.ErrFormat { if err == imagemeta.ErrFormat {
return imageTypeUnknown, errSourceImageTypeNotSupported return imageTypeUnknown, errSourceImageTypeNotSupported
} }
if err != nil { if err != nil {
return imageTypeUnknown, newUnexpectedError(err.Error(), 0) return imageTypeUnknown, newUnexpectedError(err.Error(), 0)
} }
imgtype, imgtypeOk := imageTypes[meta.Format] imgtype, imgtypeOk := imageTypes[meta.Format()]
if !imgtypeOk || !imageTypeLoadSupport(imgtype) { if !imgtypeOk || !imageTypeLoadSupport(imgtype) {
return imageTypeUnknown, errSourceImageTypeNotSupported return imageTypeUnknown, errSourceImageTypeNotSupported
} }
if err = checkDimensions(meta.Width, meta.Height); err != nil { if err = checkDimensions(meta.Width(), meta.Height()); err != nil {
return imageTypeUnknown, err return imageTypeUnknown, err
} }

View File

@ -1,4 +1,4 @@
package imagesize package imagemeta
import ( import (
"bytes" "bytes"
@ -12,7 +12,7 @@ type BmpFormatError string
func (e BmpFormatError) Error() string { return "invalid BMP format: " + string(e) } func (e BmpFormatError) Error() string { return "invalid BMP format: " + string(e) }
func DecodeBmpMeta(r io.Reader) (*Meta, error) { func DecodeBmpMeta(r io.Reader) (Meta, error) {
var tmp [26]byte var tmp [26]byte
if _, err := io.ReadFull(r, tmp[:]); err != nil { if _, err := io.ReadFull(r, tmp[:]); err != nil {
@ -36,10 +36,10 @@ func DecodeBmpMeta(r io.Reader) (*Meta, error) {
height = int(binary.LittleEndian.Uint16(tmp[20:22])) height = int(binary.LittleEndian.Uint16(tmp[20:22]))
} }
return &Meta{ return &meta{
Format: "bmp", format: "bmp",
Width: width, width: width,
Height: height, height: height,
}, nil }, nil
} }

View File

@ -1,10 +1,10 @@
package imagesize package imagemeta
import ( import (
"io" "io"
) )
func DecodeGifMeta(r io.Reader) (*Meta, error) { func DecodeGifMeta(r io.Reader) (Meta, error) {
var tmp [10]byte var tmp [10]byte
_, err := io.ReadFull(r, tmp[:]) _, err := io.ReadFull(r, tmp[:])
@ -12,10 +12,10 @@ func DecodeGifMeta(r io.Reader) (*Meta, error) {
return nil, err return nil, err
} }
return &Meta{ return &meta{
Format: "gif", format: "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
} }

View File

@ -1,4 +1,4 @@
package imagesize package imagemeta
import ( import (
"bytes" "bytes"
@ -169,17 +169,17 @@ func heicReadBoxes(d *heicDimensionsData, r io.Reader) error {
} }
} }
func DecodeHeicMeta(r io.Reader) (*Meta, error) { func DecodeHeicMeta(r io.Reader) (Meta, error) {
d := new(heicDimensionsData) d := new(heicDimensionsData)
if err := heicReadBoxes(d, r); err != nil && !d.IsFilled() { if err := heicReadBoxes(d, r); err != nil && !d.IsFilled() {
return nil, err return nil, err
} }
return &Meta{ return &meta{
Format: "heic", format: "heic",
Width: int(d.Width), width: int(d.Width),
Height: int(d.Height), height: int(d.Height),
}, nil }, nil
} }

View File

@ -1,10 +1,24 @@
package imagesize package imagemeta
import ( import (
"encoding/binary" "encoding/binary"
"io" "io"
) )
type IcoMeta struct {
Meta
offset int
size int
}
func (m *IcoMeta) BestImageOffset() int {
return m.offset
}
func (m *IcoMeta) BestImageSize() int {
return m.size
}
func icoBestSize(r io.Reader) (width, height byte, offset uint32, size uint32, err error) { func icoBestSize(r io.Reader) (width, height byte, offset uint32, size uint32, err error) {
var tmp [16]byte var tmp [16]byte
@ -35,8 +49,8 @@ func BestIcoPage(r io.Reader) (int, int, error) {
return int(offset), int(size), err return int(offset), int(size), err
} }
func DecodeIcoMeta(r io.Reader) (*Meta, error) { func DecodeIcoMeta(r io.Reader) (*IcoMeta, error) {
bwidth, bheight, _, _, err := icoBestSize(r) bwidth, bheight, offset, size, err := icoBestSize(r)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -52,13 +66,20 @@ func DecodeIcoMeta(r io.Reader) (*Meta, error) {
height = 256 height = 256
} }
return &Meta{ return &IcoMeta{
Format: "ico", Meta: &meta{
Width: width, format: "ico",
Height: height, width: width,
height: height,
},
offset: int(offset),
size: int(size),
}, nil }, nil
} }
func init() { func init() {
RegisterFormat("\x00\x00\x01\x00", DecodeIcoMeta) RegisterFormat(
"\x00\x00\x01\x00",
func(r io.Reader) (Meta, error) { return DecodeIcoMeta(r) },
)
} }

View File

@ -1,4 +1,4 @@
package imagesize package imagemeta
import ( import (
"bufio" "bufio"
@ -8,14 +8,34 @@ import (
"sync/atomic" "sync/atomic"
) )
type Meta struct { type Meta interface {
Format string Format() string
Width, Height int Width() int
Height() int
}
type DecodeMetaFunc func(io.Reader) (Meta, error)
type meta struct {
format string
width, height int
}
func (m *meta) Format() string {
return m.format
}
func (m *meta) Width() int {
return m.width
}
func (m *meta) Height() int {
return m.height
} }
type format struct { type format struct {
magic string magic string
decodeMeta func(io.Reader) (*Meta, error) decodeMeta DecodeMetaFunc
} }
type reader interface { type reader interface {
@ -49,7 +69,7 @@ func matchMagic(magic string, b []byte) bool {
return true return true
} }
func RegisterFormat(magic string, decodeMeta func(io.Reader) (*Meta, error)) { func RegisterFormat(magic string, decodeMeta DecodeMetaFunc) {
formatsMu.Lock() formatsMu.Lock()
defer formatsMu.Unlock() defer formatsMu.Unlock()
@ -57,7 +77,7 @@ func RegisterFormat(magic string, decodeMeta func(io.Reader) (*Meta, error)) {
atomicFormats.Store(append(formats, format{magic, decodeMeta})) atomicFormats.Store(append(formats, format{magic, decodeMeta}))
} }
func DecodeMeta(r io.Reader) (*Meta, error) { func DecodeMeta(r io.Reader) (Meta, error) {
rr := asReader(r) rr := asReader(r)
formats, _ := atomicFormats.Load().([]format) formats, _ := atomicFormats.Load().([]format)

View File

@ -1,4 +1,4 @@
package imagesize package imagemeta
import ( import (
"bufio" "bufio"
@ -32,7 +32,7 @@ type JpegFormatError string
func (e JpegFormatError) Error() string { return "invalid JPEG format: " + string(e) } func (e JpegFormatError) Error() string { return "invalid JPEG format: " + string(e) }
func DecodeJpegMeta(rr io.Reader) (*Meta, error) { func DecodeJpegMeta(rr io.Reader) (Meta, error) {
var tmp [512]byte var tmp [512]byte
r := asJpegReader(rr) r := asJpegReader(rr)
@ -100,10 +100,10 @@ func DecodeJpegMeta(rr io.Reader) (*Meta, error) {
return nil, JpegFormatError("unsupported precision") return nil, JpegFormatError("unsupported precision")
} }
return &Meta{ return &meta{
Format: "jpeg", format: "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
} }

View File

@ -1,4 +1,4 @@
package imagesize package imagemeta
import ( import (
"bytes" "bytes"
@ -12,7 +12,7 @@ type PngFormatError string
func (e PngFormatError) Error() string { return "invalid PNG format: " + string(e) } func (e PngFormatError) Error() string { return "invalid PNG format: " + string(e) }
func DecodePngMeta(r io.Reader) (*Meta, error) { func DecodePngMeta(r io.Reader) (Meta, error) {
var tmp [16]byte var tmp [16]byte
if _, err := io.ReadFull(r, tmp[:8]); err != nil { if _, err := io.ReadFull(r, tmp[:8]); err != nil {
@ -27,10 +27,10 @@ func DecodePngMeta(r io.Reader) (*Meta, error) {
return nil, err return nil, err
} }
return &Meta{ return &meta{
Format: "png", format: "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
} }

View File

@ -1,4 +1,4 @@
package imagesize package imagemeta
import ( import (
"io" "io"
@ -7,8 +7,8 @@ import (
func init() { func init() {
// Register fake svg decoder. Since we need this only for type detecting, we can // Register fake svg decoder. Since we need this only for type detecting, we can
// return fake image sizes // return fake image sizes
decodeMeta := func(io.Reader) (*Meta, error) { decodeMeta := func(io.Reader) (Meta, error) {
return &Meta{Format: "svg", Width: 1, Height: 1}, nil return &meta{format: "svg", width: 1, height: 1}, nil
} }
RegisterFormat("<?xml ", decodeMeta) RegisterFormat("<?xml ", decodeMeta)
RegisterFormat("<svg", decodeMeta) RegisterFormat("<svg", decodeMeta)

View File

@ -1,4 +1,4 @@
package imagesize package imagemeta
import ( import (
"bufio" "bufio"
@ -37,7 +37,7 @@ type TiffFormatError string
func (e TiffFormatError) Error() string { return "invalid TIFF format: " + string(e) } func (e TiffFormatError) Error() string { return "invalid TIFF format: " + string(e) }
func DecodeTiffMeta(rr io.Reader) (*Meta, error) { func DecodeTiffMeta(rr io.Reader) (Meta, error) {
var ( var (
tmp [12]byte tmp [12]byte
byteOrder binary.ByteOrder byteOrder binary.ByteOrder
@ -104,10 +104,10 @@ func DecodeTiffMeta(rr io.Reader) (*Meta, error) {
} }
if width > 0 && height > 0 { if width > 0 && height > 0 {
return &Meta{ return &meta{
Format: "tiff", format: "tiff",
Width: width, width: width,
Height: height, height: height,
}, nil }, nil
} }
} }

View File

@ -4,7 +4,7 @@
// Original code was cropped and fixed by @DarthSim for imgproxy needs // Original code was cropped and fixed by @DarthSim for imgproxy needs
package imagesize package imagemeta
import ( import (
"errors" "errors"
@ -25,7 +25,7 @@ var (
webpFccWEBP = riff.FourCC{'W', 'E', 'B', 'P'} webpFccWEBP = riff.FourCC{'W', 'E', 'B', 'P'}
) )
func DecodeWebpMeta(r io.Reader) (*Meta, error) { func DecodeWebpMeta(r io.Reader) (Meta, error) {
formType, riffReader, err := riff.NewReader(r) formType, riffReader, err := riff.NewReader(r)
if err != nil { if err != nil {
return nil, err return nil, err
@ -58,10 +58,10 @@ func DecodeWebpMeta(r io.Reader) (*Meta, error) {
fh, err := d.DecodeFrameHeader() fh, err := d.DecodeFrameHeader()
return &Meta{ return &meta{
Format: "webp", format: "webp",
Width: fh.Width, width: fh.Width,
Height: fh.Height, height: fh.Height,
}, err }, err
case webpFccVP8L: case webpFccVP8L:
@ -70,10 +70,10 @@ func DecodeWebpMeta(r io.Reader) (*Meta, error) {
return nil, err return nil, err
} }
return &Meta{ return &meta{
Format: "webp", format: "webp",
Width: conf.Width, width: conf.Width,
Height: conf.Height, height: conf.Height,
}, nil }, nil
case webpFccVP8X: case webpFccVP8X:
@ -88,10 +88,10 @@ func DecodeWebpMeta(r io.Reader) (*Meta, error) {
widthMinusOne := uint32(buf[4]) | uint32(buf[5])<<8 | uint32(buf[6])<<16 widthMinusOne := uint32(buf[4]) | uint32(buf[5])<<8 | uint32(buf[6])<<16
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: "webp",
Width: int(widthMinusOne) + 1, width: int(widthMinusOne) + 1,
Height: int(heightMinusOne) + 1, height: int(heightMinusOne) + 1,
}, nil }, nil
default: default:

View File

@ -7,7 +7,7 @@ import (
"math" "math"
"runtime" "runtime"
imagesize "github.com/imgproxy/imgproxy/image_size" "github.com/imgproxy/imgproxy/imagemeta"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
) )
@ -564,26 +564,29 @@ func transformAnimated(ctx context.Context, img *vipsImage, data []byte, po *pro
} }
func getIcoData(imgdata *imageData) (*imageData, error) { func getIcoData(imgdata *imageData) (*imageData, error) {
offset, size, err := imagesize.BestIcoPage(bytes.NewBuffer(imgdata.Data)) icoMeta, err := imagemeta.DecodeIcoMeta(bytes.NewReader(imgdata.Data))
if err != nil { if err != nil {
return nil, err return nil, err
} }
offset := icoMeta.BestImageOffset()
size := icoMeta.BestImageSize()
data := imgdata.Data[offset : offset+size] data := imgdata.Data[offset : offset+size]
meta, err := imagesize.DecodeMeta(bytes.NewBuffer(data)) meta, err := imagemeta.DecodeMeta(bytes.NewReader(data))
if err != nil { if err != nil {
return nil, err return nil, err
} }
if imgtype, ok := imageTypes[meta.Format]; ok && vipsTypeSupportLoad[imgtype] { if imgtype, ok := imageTypes[meta.Format()]; ok && vipsTypeSupportLoad[imgtype] {
return &imageData{ return &imageData{
Data: data, Data: data,
Type: imgtype, Type: imgtype,
}, nil }, nil
} }
return nil, fmt.Errorf("Can't load %s from ICO", meta.Format) return nil, fmt.Errorf("Can't load %s from ICO", meta.Format())
} }
func saveImageToFitBytes(po *processingOptions, img *vipsImage) ([]byte, context.CancelFunc, error) { func saveImageToFitBytes(po *processingOptions, img *vipsImage) ([]byte, context.CancelFunc, error) {

View File

@ -12,7 +12,7 @@ import (
"strings" "strings"
"sync" "sync"
structdiff "github.com/imgproxy/imgproxy/struct-diff" "github.com/imgproxy/imgproxy/structdiff"
) )
type urlOption struct { type urlOption struct {