mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-07-02 22:46:50 +02:00
Rename processing options constants and move them to processing_options.go
This commit is contained in:
14
download.go
14
download.go
@ -80,16 +80,16 @@ func checkTypeAndDimensions(r io.Reader) (imageType, error) {
|
|||||||
imgtype, imgtypeOk := imageTypes[imgtypeStr]
|
imgtype, imgtypeOk := imageTypes[imgtypeStr]
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return UNKNOWN, err
|
return imageTypeUnknown, err
|
||||||
}
|
}
|
||||||
if imgconf.Width > conf.MaxSrcDimension || imgconf.Height > conf.MaxSrcDimension {
|
if imgconf.Width > conf.MaxSrcDimension || imgconf.Height > conf.MaxSrcDimension {
|
||||||
return UNKNOWN, errors.New("Source image is too big")
|
return imageTypeUnknown, errors.New("Source image is too big")
|
||||||
}
|
}
|
||||||
if imgconf.Width*imgconf.Height > conf.MaxSrcResolution {
|
if imgconf.Width*imgconf.Height > conf.MaxSrcResolution {
|
||||||
return UNKNOWN, errors.New("Source image is too big")
|
return imageTypeUnknown, errors.New("Source image is too big")
|
||||||
}
|
}
|
||||||
if !imgtypeOk || !vipsTypeSupportLoad[imgtype] {
|
if !imgtypeOk || !vipsTypeSupportLoad[imgtype] {
|
||||||
return UNKNOWN, errors.New("Source image type not supported")
|
return imageTypeUnknown, errors.New("Source image type not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
return imgtype, nil
|
return imgtype, nil
|
||||||
@ -100,7 +100,7 @@ func readAndCheckImage(res *http.Response) ([]byte, imageType, error) {
|
|||||||
|
|
||||||
imgtype, err := checkTypeAndDimensions(nr)
|
imgtype, err := checkTypeAndDimensions(nr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, UNKNOWN, err
|
return nil, imageTypeUnknown, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.ContentLength > 0 {
|
if res.ContentLength > 0 {
|
||||||
@ -117,13 +117,13 @@ func downloadImage(url string) ([]byte, imageType, error) {
|
|||||||
|
|
||||||
res, err := downloadClient.Get(fullURL)
|
res, err := downloadClient.Get(fullURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, UNKNOWN, err
|
return nil, imageTypeUnknown, err
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
if res.StatusCode != 200 {
|
if res.StatusCode != 200 {
|
||||||
body, _ := ioutil.ReadAll(res.Body)
|
body, _ := ioutil.ReadAll(res.Body)
|
||||||
return nil, UNKNOWN, fmt.Errorf("Can't download image; Status: %d; %s", res.StatusCode, string(body))
|
return nil, imageTypeUnknown, fmt.Errorf("Can't download image; Status: %d; %s", res.StatusCode, string(body))
|
||||||
}
|
}
|
||||||
|
|
||||||
return readAndCheckImage(res)
|
return readAndCheckImage(res)
|
||||||
|
7
image_types.h
Normal file
7
image_types.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
enum types {
|
||||||
|
UNKNOWN = 0,
|
||||||
|
JPEG,
|
||||||
|
PNG,
|
||||||
|
WEBP,
|
||||||
|
GIF
|
||||||
|
};
|
108
process.go
108
process.go
@ -16,52 +16,6 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
type imageType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
UNKNOWN = C.UNKNOWN
|
|
||||||
JPEG = C.JPEG
|
|
||||||
PNG = C.PNG
|
|
||||||
WEBP = C.WEBP
|
|
||||||
GIF = C.GIF
|
|
||||||
)
|
|
||||||
|
|
||||||
var imageTypes = map[string]imageType{
|
|
||||||
"jpeg": JPEG,
|
|
||||||
"jpg": JPEG,
|
|
||||||
"png": PNG,
|
|
||||||
"webp": WEBP,
|
|
||||||
"gif": GIF,
|
|
||||||
}
|
|
||||||
|
|
||||||
type gravityType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
CENTER gravityType = iota
|
|
||||||
NORTH
|
|
||||||
EAST
|
|
||||||
SOUTH
|
|
||||||
WEST
|
|
||||||
SMART
|
|
||||||
)
|
|
||||||
|
|
||||||
var gravityTypes = map[string]gravityType{
|
|
||||||
"ce": CENTER,
|
|
||||||
"no": NORTH,
|
|
||||||
"ea": EAST,
|
|
||||||
"so": SOUTH,
|
|
||||||
"we": WEST,
|
|
||||||
"sm": SMART,
|
|
||||||
}
|
|
||||||
|
|
||||||
type resizeType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
FIT resizeType = iota
|
|
||||||
FILL
|
|
||||||
CROP
|
|
||||||
)
|
|
||||||
|
|
||||||
var vipsSupportSmartcrop bool
|
var vipsSupportSmartcrop bool
|
||||||
var vipsTypeSupportLoad = make(map[imageType]bool)
|
var vipsTypeSupportLoad = make(map[imageType]bool)
|
||||||
var vipsTypeSupportSave = make(map[imageType]bool)
|
var vipsTypeSupportSave = make(map[imageType]bool)
|
||||||
@ -98,27 +52,27 @@ func initVips() {
|
|||||||
|
|
||||||
vipsSupportSmartcrop = C.vips_support_smartcrop() == 1
|
vipsSupportSmartcrop = C.vips_support_smartcrop() == 1
|
||||||
|
|
||||||
if int(C.vips_type_find_load_go(C.JPEG)) != 0 {
|
if int(C.vips_type_find_load_go(imageTypeJPEG)) != 0 {
|
||||||
vipsTypeSupportLoad[JPEG] = true
|
vipsTypeSupportLoad[imageTypeJPEG] = true
|
||||||
}
|
}
|
||||||
if int(C.vips_type_find_load_go(C.PNG)) != 0 {
|
if int(C.vips_type_find_load_go(imageTypePNG)) != 0 {
|
||||||
vipsTypeSupportLoad[PNG] = true
|
vipsTypeSupportLoad[imageTypePNG] = true
|
||||||
}
|
}
|
||||||
if int(C.vips_type_find_load_go(C.WEBP)) != 0 {
|
if int(C.vips_type_find_load_go(imageTypeWEBP)) != 0 {
|
||||||
vipsTypeSupportLoad[WEBP] = true
|
vipsTypeSupportLoad[imageTypeWEBP] = true
|
||||||
}
|
}
|
||||||
if int(C.vips_type_find_load_go(C.GIF)) != 0 {
|
if int(C.vips_type_find_load_go(imageTypeGIF)) != 0 {
|
||||||
vipsTypeSupportLoad[GIF] = true
|
vipsTypeSupportLoad[imageTypeGIF] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if int(C.vips_type_find_save_go(C.JPEG)) != 0 {
|
if int(C.vips_type_find_save_go(imageTypeJPEG)) != 0 {
|
||||||
vipsTypeSupportSave[JPEG] = true
|
vipsTypeSupportSave[imageTypeJPEG] = true
|
||||||
}
|
}
|
||||||
if int(C.vips_type_find_save_go(C.PNG)) != 0 {
|
if int(C.vips_type_find_save_go(imageTypePNG)) != 0 {
|
||||||
vipsTypeSupportSave[PNG] = true
|
vipsTypeSupportSave[imageTypePNG] = true
|
||||||
}
|
}
|
||||||
if int(C.vips_type_find_save_go(C.WEBP)) != 0 {
|
if int(C.vips_type_find_save_go(imageTypeWEBP)) != 0 {
|
||||||
vipsTypeSupportSave[WEBP] = true
|
vipsTypeSupportSave[imageTypeWEBP] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
cConf.Quality = C.int(conf.Quality)
|
cConf.Quality = C.int(conf.Quality)
|
||||||
@ -137,7 +91,7 @@ func shutdownVips() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func randomAccessRequired(po processingOptions) int {
|
func randomAccessRequired(po processingOptions) int {
|
||||||
if po.Gravity == SMART {
|
if po.Gravity == gravitySmart {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
@ -175,7 +129,7 @@ func extractMeta(img *C.VipsImage) (int, int, int, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func calcScale(width, height int, po processingOptions) float64 {
|
func calcScale(width, height int, po processingOptions) float64 {
|
||||||
if (po.Width == width && po.Height == height) || (po.Resize != FILL && po.Resize != FIT) {
|
if (po.Width == width && po.Height == height) || (po.Resize != resizeFill && po.Resize != resizeFit) {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +138,7 @@ func calcScale(width, height int, po processingOptions) float64 {
|
|||||||
wr := fow / fsw
|
wr := fow / fsw
|
||||||
hr := foh / fsh
|
hr := foh / fsh
|
||||||
|
|
||||||
if po.Resize == FIT {
|
if po.Resize == resizeFit {
|
||||||
return math.Min(wr, hr)
|
return math.Min(wr, hr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +148,7 @@ func calcScale(width, height int, po processingOptions) float64 {
|
|||||||
func calcShink(scale float64, imgtype imageType) int {
|
func calcShink(scale float64, imgtype imageType) int {
|
||||||
shrink := int(1.0 / scale)
|
shrink := int(1.0 / scale)
|
||||||
|
|
||||||
if imgtype != JPEG {
|
if imgtype != imageTypeJPEG {
|
||||||
return shrink
|
return shrink
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,19 +168,19 @@ func calcCrop(width, height int, po processingOptions) (left, top int) {
|
|||||||
left = (width - po.Width + 1) / 2
|
left = (width - po.Width + 1) / 2
|
||||||
top = (height - po.Height + 1) / 2
|
top = (height - po.Height + 1) / 2
|
||||||
|
|
||||||
if po.Gravity == NORTH {
|
if po.Gravity == gravityNorth {
|
||||||
top = 0
|
top = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if po.Gravity == EAST {
|
if po.Gravity == gravityEast {
|
||||||
left = width - po.Width
|
left = width - po.Width
|
||||||
}
|
}
|
||||||
|
|
||||||
if po.Gravity == SOUTH {
|
if po.Gravity == gravitySouth {
|
||||||
top = height - po.Height
|
top = height - po.Height
|
||||||
}
|
}
|
||||||
|
|
||||||
if po.Gravity == WEST {
|
if po.Gravity == gravityWest {
|
||||||
left = 0
|
left = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +191,7 @@ func processImage(data []byte, imgtype imageType, po processingOptions, t *timer
|
|||||||
defer C.vips_cleanup()
|
defer C.vips_cleanup()
|
||||||
defer runtime.KeepAlive(data)
|
defer runtime.KeepAlive(data)
|
||||||
|
|
||||||
if po.Gravity == SMART && !vipsSupportSmartcrop {
|
if po.Gravity == gravitySmart && !vipsSupportSmartcrop {
|
||||||
return nil, errors.New("Smart crop is not supported by used version of libvips")
|
return nil, errors.New("Smart crop is not supported by used version of libvips")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,7 +206,7 @@ func processImage(data []byte, imgtype imageType, po processingOptions, t *timer
|
|||||||
imgWidth, imgHeight, angle, flip := extractMeta(img)
|
imgWidth, imgHeight, angle, flip := extractMeta(img)
|
||||||
|
|
||||||
// Ensure we won't crop out of bounds
|
// Ensure we won't crop out of bounds
|
||||||
if !po.Enlarge || po.Resize == CROP {
|
if !po.Enlarge || po.Resize == resizeCrop {
|
||||||
if imgWidth < po.Width {
|
if imgWidth < po.Width {
|
||||||
po.Width = imgWidth
|
po.Width = imgWidth
|
||||||
}
|
}
|
||||||
@ -263,12 +217,12 @@ func processImage(data []byte, imgtype imageType, po processingOptions, t *timer
|
|||||||
}
|
}
|
||||||
|
|
||||||
if po.Width != imgWidth || po.Height != imgHeight {
|
if po.Width != imgWidth || po.Height != imgHeight {
|
||||||
if po.Resize == FILL || po.Resize == FIT {
|
if po.Resize == resizeFill || po.Resize == resizeFit {
|
||||||
scale := calcScale(imgWidth, imgHeight, po)
|
scale := calcScale(imgWidth, imgHeight, po)
|
||||||
|
|
||||||
// Do some shrink-on-load
|
// Do some shrink-on-load
|
||||||
if scale < 1.0 {
|
if scale < 1.0 {
|
||||||
if imgtype == JPEG || imgtype == WEBP {
|
if imgtype == imageTypeJPEG || imgtype == imageTypeWEBP {
|
||||||
shrink := calcShink(scale, imgtype)
|
shrink := calcShink(scale, imgtype)
|
||||||
scale = scale * float64(shrink)
|
scale = scale * float64(shrink)
|
||||||
|
|
||||||
@ -332,8 +286,8 @@ func processImage(data []byte, imgtype imageType, po processingOptions, t *timer
|
|||||||
|
|
||||||
t.Check()
|
t.Check()
|
||||||
|
|
||||||
if (po.Width != imgWidth || po.Height != imgHeight) && (po.Resize == FILL || po.Resize == CROP) {
|
if (po.Width != imgWidth || po.Height != imgHeight) && (po.Resize == resizeFill || po.Resize == resizeCrop) {
|
||||||
if po.Gravity == SMART {
|
if po.Gravity == gravitySmart {
|
||||||
if err = vipsImageCopyMemory(&img); err != nil {
|
if err = vipsImageCopyMemory(&img); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -370,11 +324,11 @@ func vipsSaveImage(img *C.struct__VipsImage, imgtype imageType) ([]byte, error)
|
|||||||
imgsize := C.size_t(0)
|
imgsize := C.size_t(0)
|
||||||
|
|
||||||
switch imgtype {
|
switch imgtype {
|
||||||
case JPEG:
|
case imageTypeJPEG:
|
||||||
err = C.vips_jpegsave_go(img, &ptr, &imgsize, 1, cConf.Quality, cConf.JpegProgressive)
|
err = C.vips_jpegsave_go(img, &ptr, &imgsize, 1, cConf.Quality, cConf.JpegProgressive)
|
||||||
case PNG:
|
case imageTypePNG:
|
||||||
err = C.vips_pngsave_go(img, &ptr, &imgsize, cConf.PngInterlaced)
|
err = C.vips_pngsave_go(img, &ptr, &imgsize, cConf.PngInterlaced)
|
||||||
case WEBP:
|
case imageTypeWEBP:
|
||||||
err = C.vips_webpsave_go(img, &ptr, &imgsize, 1, cConf.Quality)
|
err = C.vips_webpsave_go(img, &ptr, &imgsize, 1, cConf.Quality)
|
||||||
}
|
}
|
||||||
if err != 0 {
|
if err != 0 {
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo LDFLAGS: -s -w
|
||||||
|
#include <image_types.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"C"
|
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -10,10 +15,56 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type imageType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
imageTypeUnknown = C.UNKNOWN
|
||||||
|
imageTypeJPEG = C.JPEG
|
||||||
|
imageTypePNG = C.PNG
|
||||||
|
imageTypeWEBP = C.WEBP
|
||||||
|
imageTypeGIF = C.GIF
|
||||||
|
)
|
||||||
|
|
||||||
|
var imageTypes = map[string]imageType{
|
||||||
|
"jpeg": imageTypeJPEG,
|
||||||
|
"jpg": imageTypeJPEG,
|
||||||
|
"png": imageTypePNG,
|
||||||
|
"webp": imageTypeWEBP,
|
||||||
|
"gif": imageTypeGIF,
|
||||||
|
}
|
||||||
|
|
||||||
|
type gravityType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
gravityCenter gravityType = iota
|
||||||
|
gravityNorth
|
||||||
|
gravityEast
|
||||||
|
gravitySouth
|
||||||
|
gravityWest
|
||||||
|
gravitySmart
|
||||||
|
)
|
||||||
|
|
||||||
|
var gravityTypes = map[string]gravityType{
|
||||||
|
"ce": gravityCenter,
|
||||||
|
"no": gravityNorth,
|
||||||
|
"ea": gravityEast,
|
||||||
|
"so": gravitySouth,
|
||||||
|
"we": gravityWest,
|
||||||
|
"sm": gravitySmart,
|
||||||
|
}
|
||||||
|
|
||||||
|
type resizeType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
resizeFit resizeType = iota
|
||||||
|
resizeFill
|
||||||
|
resizeCrop
|
||||||
|
)
|
||||||
|
|
||||||
var resizeTypes = map[string]resizeType{
|
var resizeTypes = map[string]resizeType{
|
||||||
"fit": FIT,
|
"fit": resizeFit,
|
||||||
"fill": FILL,
|
"fill": resizeFill,
|
||||||
"crop": CROP,
|
"crop": resizeCrop,
|
||||||
}
|
}
|
||||||
|
|
||||||
type processingOptions struct {
|
type processingOptions struct {
|
||||||
@ -23,21 +74,25 @@ type processingOptions struct {
|
|||||||
Gravity gravityType
|
Gravity gravityType
|
||||||
Enlarge bool
|
Enlarge bool
|
||||||
Format imageType
|
Format imageType
|
||||||
|
Blur float32
|
||||||
|
Sharpen float32
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultProcessingOptions() processingOptions {
|
func defaultProcessingOptions() processingOptions {
|
||||||
return processingOptions{
|
return processingOptions{
|
||||||
Resize: FIT,
|
Resize: resizeFit,
|
||||||
Width: 0,
|
Width: 0,
|
||||||
Height: 0,
|
Height: 0,
|
||||||
Gravity: CENTER,
|
Gravity: gravityCenter,
|
||||||
Enlarge: false,
|
Enlarge: false,
|
||||||
Format: JPEG,
|
Format: imageTypeJPEG,
|
||||||
|
Blur: 0,
|
||||||
|
Sharpen: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeUrl(parts []string) (string, imageType, error) {
|
func decodeURL(parts []string) (string, imageType, error) {
|
||||||
var imgType imageType = JPEG
|
var imgType imageType = imageTypeJPEG
|
||||||
|
|
||||||
urlParts := strings.Split(strings.Join(parts, ""), ".")
|
urlParts := strings.Split(strings.Join(parts, ""), ".")
|
||||||
|
|
||||||
@ -218,7 +273,7 @@ func parsePathAdvanced(parts []string) (string, processingOptions, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
url, imgType, err := decodeUrl(parts[urlStart:])
|
url, imgType, err := decodeURL(parts[urlStart:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", po, err
|
return "", po, err
|
||||||
}
|
}
|
||||||
@ -256,7 +311,7 @@ func parsePathSimple(parts []string) (string, processingOptions, error) {
|
|||||||
return "", po, err
|
return "", po, err
|
||||||
}
|
}
|
||||||
|
|
||||||
url, imgType, err := decodeUrl(parts[5:])
|
url, imgType, err := decodeURL(parts[5:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", po, err
|
return "", po, err
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var mimes = map[imageType]string{
|
var mimes = map[imageType]string{
|
||||||
JPEG: "image/jpeg",
|
imageTypeJPEG: "image/jpeg",
|
||||||
PNG: "image/png",
|
imageTypePNG: "image/png",
|
||||||
WEBP: "image/webp",
|
imageTypeWEBP: "image/webp",
|
||||||
}
|
}
|
||||||
|
|
||||||
type httpHandler struct {
|
type httpHandler struct {
|
||||||
|
9
vips.h
9
vips.h
@ -1,6 +1,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <vips/vips.h>
|
#include <vips/vips.h>
|
||||||
#include <vips/vips7compat.h>
|
#include <vips/vips7compat.h>
|
||||||
|
#include <image_types.h>
|
||||||
|
|
||||||
#define VIPS_SUPPORT_SMARTCROP \
|
#define VIPS_SUPPORT_SMARTCROP \
|
||||||
(VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 5))
|
(VIPS_MAJOR_VERSION > 8 || (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION >= 5))
|
||||||
@ -13,14 +14,6 @@
|
|||||||
|
|
||||||
#define EXIF_ORIENTATION "exif-ifd0-Orientation"
|
#define EXIF_ORIENTATION "exif-ifd0-Orientation"
|
||||||
|
|
||||||
enum types {
|
|
||||||
UNKNOWN = 0,
|
|
||||||
JPEG,
|
|
||||||
PNG,
|
|
||||||
WEBP,
|
|
||||||
GIF
|
|
||||||
};
|
|
||||||
|
|
||||||
int
|
int
|
||||||
vips_initialize() {
|
vips_initialize() {
|
||||||
return vips_init("imgproxy");
|
return vips_init("imgproxy");
|
||||||
|
Reference in New Issue
Block a user