mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-02-07 11:36:25 +02:00
Load ICO without imagemagick
This commit is contained in:
parent
bda7e1e53d
commit
a3d894a697
@ -5,7 +5,7 @@ import (
|
||||
"io"
|
||||
)
|
||||
|
||||
func icoBestSize(r io.Reader) (width, height byte, page uint16, err error) {
|
||||
func icoBestSize(r io.Reader) (width, height byte, offset uint32, size uint32, err error) {
|
||||
var tmp [16]byte
|
||||
|
||||
if _, err = io.ReadFull(r, tmp[:6]); err != nil {
|
||||
@ -22,20 +22,21 @@ func icoBestSize(r io.Reader) (width, height byte, page uint16, err error) {
|
||||
if tmp[0] > width || tmp[1] > height || tmp[0] == 0 || tmp[1] == 0 {
|
||||
width = tmp[0]
|
||||
height = tmp[1]
|
||||
page = i
|
||||
size = binary.LittleEndian.Uint32(tmp[8:12])
|
||||
offset = binary.LittleEndian.Uint32(tmp[12:16])
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func BestIcoPage(r io.Reader) (int, error) {
|
||||
_, _, page, err := icoBestSize(r)
|
||||
return int(page), err
|
||||
func BestIcoPage(r io.Reader) (int, int, error) {
|
||||
_, _, offset, size, err := icoBestSize(r)
|
||||
return int(offset), int(size), err
|
||||
}
|
||||
|
||||
func DecodeIcoMeta(r io.Reader) (*Meta, error) {
|
||||
bwidth, bheight, _, err := icoBestSize(r)
|
||||
bwidth, bheight, _, _, err := icoBestSize(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
39
process.go
39
process.go
@ -1,10 +1,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"runtime"
|
||||
|
||||
imageSize "github.com/imgproxy/imgproxy/image_size"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
@ -13,7 +16,9 @@ const msgSmartCropNotSupported = "Smart crop is not supported by used version of
|
||||
var errConvertingNonSvgToSvg = newError(422, "Converting non-SVG images to SVG is not supported", "Converting non-SVG images to SVG is not supported")
|
||||
|
||||
func imageTypeLoadSupport(imgtype imageType) bool {
|
||||
return imgtype == imageTypeSVG || vipsTypeSupportLoad[imgtype]
|
||||
return imgtype == imageTypeSVG ||
|
||||
imgtype == imageTypeICO ||
|
||||
vipsTypeSupportLoad[imgtype]
|
||||
}
|
||||
|
||||
func imageTypeSaveSupport(imgtype imageType) bool {
|
||||
@ -541,6 +546,29 @@ func transformAnimated(ctx context.Context, img *vipsImage, data []byte, po *pro
|
||||
return nil
|
||||
}
|
||||
|
||||
func getIcoData(imgdata *imageData) (*imageData, error) {
|
||||
offset, size, err := imageSize.BestIcoPage(bytes.NewBuffer(imgdata.Data))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data := imgdata.Data[offset : offset+size]
|
||||
|
||||
meta, err := imageSize.DecodeMeta(bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if imgtype, ok := imageTypes[meta.Format]; ok && vipsTypeSupportLoad[imgtype] {
|
||||
return &imageData{
|
||||
Data: data,
|
||||
Type: imgtype,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Can't load %s from ICO", meta.Format)
|
||||
}
|
||||
|
||||
func processImage(ctx context.Context) ([]byte, context.CancelFunc, error) {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
@ -584,6 +612,15 @@ func processImage(ctx context.Context) ([]byte, context.CancelFunc, error) {
|
||||
return []byte{}, func() {}, errSourceImageTypeNotSupported
|
||||
}
|
||||
|
||||
if imgdata.Type == imageTypeICO {
|
||||
icodata, err := getIcoData(imgdata)
|
||||
if err != nil {
|
||||
return nil, func() {}, err
|
||||
}
|
||||
|
||||
imgdata = icodata
|
||||
}
|
||||
|
||||
if !vipsSupportSmartcrop {
|
||||
if po.Gravity.Type == gravitySmart {
|
||||
logWarning(msgSmartCropNotSupported)
|
||||
|
12
vips.c
12
vips.c
@ -80,8 +80,6 @@ vips_type_find_load_go(int imgtype) {
|
||||
return vips_type_find("VipsOperation", "gifload_buffer");
|
||||
case (SVG):
|
||||
return vips_type_find("VipsOperation", "svgload_buffer");
|
||||
case (ICO):
|
||||
return vips_type_find("VipsOperation", "magickload_buffer");
|
||||
case (HEIC):
|
||||
return vips_type_find("VipsOperation", "heifload_buffer");
|
||||
case (BMP):
|
||||
@ -167,16 +165,6 @@ vips_svgload_go(void *buf, size_t len, double scale, VipsImage **out) {
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
vips_icoload_go(void *buf, size_t len, int page, VipsImage **out) {
|
||||
#if VIPS_SUPPORT_MAGICK
|
||||
return vips_magickload_buffer(buf, len, out, "access", VIPS_ACCESS_SEQUENTIAL, "page", page, NULL);
|
||||
#else
|
||||
vips_error("vips_icoload_go", "Loading ICO is not supported (libvips 8.7+ reuired)");
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
vips_heifload_go(void *buf, size_t len, VipsImage **out) {
|
||||
#if VIPS_SUPPORT_HEIF
|
||||
|
10
vips.go
10
vips.go
@ -8,15 +8,12 @@ package main
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"math"
|
||||
"os"
|
||||
"runtime"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
imageSize "github.com/imgproxy/imgproxy/image_size"
|
||||
)
|
||||
|
||||
type vipsImage struct {
|
||||
@ -157,13 +154,6 @@ func (img *vipsImage) Load(data []byte, imgtype imageType, shrink int, scale flo
|
||||
err = C.vips_gifload_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), C.int(pages), &tmp)
|
||||
case imageTypeSVG:
|
||||
err = C.vips_svgload_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), C.double(scale), &tmp)
|
||||
case imageTypeICO:
|
||||
bestPage, ierr := imageSize.BestIcoPage(bytes.NewBuffer(data))
|
||||
if ierr != nil {
|
||||
logWarning(ierr.Error())
|
||||
}
|
||||
|
||||
err = C.vips_icoload_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), C.int(bestPage), &tmp)
|
||||
case imageTypeHEIC:
|
||||
err = C.vips_heifload_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), &tmp)
|
||||
case imageTypeBMP:
|
||||
|
1
vips.h
1
vips.h
@ -32,7 +32,6 @@ int vips_pngload_go(void *buf, size_t len, VipsImage **out);
|
||||
int vips_webpload_go(void *buf, size_t len, double scale, int pages, VipsImage **out);
|
||||
int vips_gifload_go(void *buf, size_t len, int pages, VipsImage **out);
|
||||
int vips_svgload_go(void *buf, size_t len, double scale, VipsImage **out);
|
||||
int vips_icoload_go(void *buf, size_t len, int page, VipsImage **out);
|
||||
int vips_heifload_go(void *buf, size_t len, VipsImage **out);
|
||||
int vips_bmpload_go(void *buf, size_t len, VipsImage **out);
|
||||
int vips_tiffload_go(void *buf, size_t len, VipsImage **out);
|
||||
|
Loading…
x
Reference in New Issue
Block a user