mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-02-02 11:34:20 +02:00
Load ICO with vips_magickload
This commit is contained in:
parent
52152bcf47
commit
4d06d397fe
@ -47,7 +47,6 @@ RUN cd /root \
|
||||
&& curl -Ls https://github.com/libvips/libvips/releases/download/v$VIPS_VERSION/vips-$VIPS_VERSION.tar.gz | tar -xz \
|
||||
&& cd vips-$VIPS_VERSION \
|
||||
&& ./configure \
|
||||
--disable-magickload \
|
||||
--without-python \
|
||||
--without-tiff \
|
||||
--without-OpenEXR \
|
||||
|
@ -17,7 +17,7 @@ imgproxy supports GIF output only when using libvips 8.7.0+ compiled with ImageM
|
||||
|
||||
## ICO support
|
||||
|
||||
imgproxy supports ICO output only when using libvips 8.7.0+ compiled with ImageMagick support. Official imgproxy Docker image supports ICO out of the box.
|
||||
imgproxy supports ICO only when using libvips 8.7.0+ compiled with ImageMagick support. Official imgproxy Docker image supports ICO out of the box.
|
||||
|
||||
## HEIC support
|
||||
|
||||
|
1
go.mod
1
go.mod
@ -19,7 +19,6 @@ require (
|
||||
github.com/honeybadger-io/honeybadger-go v0.4.0
|
||||
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 // indirect
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/mat/besticon v3.9.0+incompatible
|
||||
github.com/matoous/go-nanoid v0.0.0-20181114085210-eab626deece6
|
||||
github.com/newrelic/go-agent v2.2.0+incompatible
|
||||
github.com/pborman/uuid v0.0.0-20180906182336-adf5a7427709 // indirect
|
||||
|
2
go.sum
2
go.sum
@ -68,8 +68,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/mat/besticon v3.9.0+incompatible h1:SLaWKCE7ptsjWbQee8Sbx8F/WK4bw8b55tUV4mY0m/c=
|
||||
github.com/mat/besticon v3.9.0+incompatible/go.mod h1:mA1auQYHt6CW5e7L9HJLmqVQC8SzNk2gVwouO0AbiEU=
|
||||
github.com/matoous/go-nanoid v0.0.0-20181114085210-eab626deece6 h1:elv0VC5n2owefO3RvtKvS3i3/rw9LCrs0+tVFLbBlmQ=
|
||||
github.com/matoous/go-nanoid v0.0.0-20181114085210-eab626deece6/go.mod h1:soqXi4beH2aAljcVvgIDqekDtnM2UZkGl47fniwq3J4=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
|
28
ico_data.go
28
ico_data.go
@ -1,28 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"image"
|
||||
"image/draw"
|
||||
|
||||
_ "github.com/mat/besticon/ico"
|
||||
)
|
||||
|
||||
func icoData(data []byte) (out []byte, width int, height int, err error) {
|
||||
var ico image.Image
|
||||
|
||||
ico, _, err = image.Decode(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Ensure that image is in RGBA format
|
||||
rgba := image.NewRGBA(ico.Bounds())
|
||||
draw.Draw(rgba, ico.Bounds(), ico, image.Point{}, draw.Src)
|
||||
|
||||
width = rgba.Bounds().Dx()
|
||||
height = rgba.Bounds().Dy()
|
||||
out = rgba.Pix
|
||||
|
||||
return
|
||||
}
|
@ -5,32 +5,56 @@ import (
|
||||
"io"
|
||||
)
|
||||
|
||||
func DecodeIcoMeta(r io.Reader) (*Meta, error) {
|
||||
func icoBestSize(r io.Reader) (width, height byte, page uint16, err error) {
|
||||
var tmp [16]byte
|
||||
|
||||
if _, err := io.ReadFull(r, tmp[:6]); err != nil {
|
||||
return nil, err
|
||||
if _, err = io.ReadFull(r, tmp[:6]); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
count := binary.LittleEndian.Uint16(tmp[4:6])
|
||||
|
||||
width, height := byte(0), byte(0)
|
||||
|
||||
for i := uint16(0); i < count; i++ {
|
||||
if _, err := io.ReadFull(r, tmp[:]); err != nil {
|
||||
return nil, err
|
||||
if _, err = io.ReadFull(r, tmp[:]); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if tmp[0] > width || tmp[1] > height {
|
||||
if tmp[0] > width || tmp[1] > height || tmp[0] == 0 || tmp[1] == 0 {
|
||||
width = tmp[0]
|
||||
height = tmp[1]
|
||||
page = i
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func BestIcoPage(r io.Reader) (int, error) {
|
||||
_, _, page, err := icoBestSize(r)
|
||||
return int(page), err
|
||||
}
|
||||
|
||||
func DecodeIcoMeta(r io.Reader) (*Meta, error) {
|
||||
bwidth, bheight, _, err := icoBestSize(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
width := int(bwidth)
|
||||
height := int(bheight)
|
||||
|
||||
if width == 0 {
|
||||
width = 256
|
||||
}
|
||||
|
||||
if height == 0 {
|
||||
height = 256
|
||||
}
|
||||
|
||||
return &Meta{
|
||||
Format: "ico",
|
||||
Width: int(width),
|
||||
Height: int(height),
|
||||
Width: width,
|
||||
Height: height,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
12
vips.c
12
vips.c
@ -80,6 +80,8 @@ 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 (TIFF):
|
||||
@ -161,6 +163,16 @@ 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
|
||||
|
17
vips.go
17
vips.go
@ -8,12 +8,15 @@ package main
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"math"
|
||||
"os"
|
||||
"runtime"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
imageSize "github.com/imgproxy/imgproxy/image_size"
|
||||
)
|
||||
|
||||
type vipsImage struct {
|
||||
@ -88,6 +91,9 @@ func initVips() {
|
||||
if int(C.vips_type_find_load_go(C.int(imageTypeSVG))) != 0 {
|
||||
vipsTypeSupportLoad[imageTypeSVG] = true
|
||||
}
|
||||
if int(C.vips_type_find_load_go(C.int(imageTypeICO))) != 0 {
|
||||
vipsTypeSupportLoad[imageTypeICO] = true
|
||||
}
|
||||
if int(C.vips_type_find_load_go(C.int(imageTypeHEIC))) != 0 {
|
||||
vipsTypeSupportLoad[imageTypeHEIC] = true
|
||||
}
|
||||
@ -95,9 +101,6 @@ func initVips() {
|
||||
vipsTypeSupportLoad[imageTypeTIFF] = true
|
||||
}
|
||||
|
||||
// we load ICO with github.com/mat/besticon/ico and send decoded data to vips
|
||||
vipsTypeSupportLoad[imageTypeICO] = true
|
||||
|
||||
if int(C.vips_type_find_save_go(C.int(imageTypeJPEG))) != 0 {
|
||||
vipsTypeSupportSave[imageTypeJPEG] = true
|
||||
}
|
||||
@ -197,12 +200,12 @@ func (img *vipsImage) Load(data []byte, imgtype imageType, shrink int, scale flo
|
||||
case imageTypeSVG:
|
||||
err = C.vips_svgload_go(unsafe.Pointer(&data[0]), C.size_t(len(data)), C.double(scale), &tmp)
|
||||
case imageTypeICO:
|
||||
rawData, width, height, icoErr := icoData(data)
|
||||
if icoErr != nil {
|
||||
return icoErr
|
||||
bestPage, ierr := imageSize.BestIcoPage(bytes.NewBuffer(data))
|
||||
if ierr != nil {
|
||||
logWarning(ierr.Error())
|
||||
}
|
||||
|
||||
tmp = C.vips_image_new_from_memory_copy(unsafe.Pointer(&rawData[0]), C.size_t(width*height*4), C.int(width), C.int(height), 4, C.VIPS_FORMAT_UCHAR)
|
||||
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 imageTypeTIFF:
|
||||
|
1
vips.h
1
vips.h
@ -31,6 +31,7 @@ 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_tiffload_go(void *buf, size_t len, VipsImage **out);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user