Browse Source

Merge branch 'feature/webp-effort-preset'

DarthSim 2 weeks ago
parent
commit
91abc6f385
6 changed files with 90 additions and 3 deletions
  1. 14 0
      config/config.go
  2. 12 0
      config/configurators/configurators.go
  3. 41 0
      config/webp_preset.go
  4. 3 1
      vips/vips.c
  5. 19 1
      vips/vips.go
  6. 1 1
      vips/vips.h

+ 14 - 0
config/config.go

@@ -57,6 +57,8 @@ var (
 	PngQuantizationColors int
 	AvifSpeed             int
 	JxlEffort             int
+	WebpEffort            int
+	WebpPreset            WebpPresetKind
 	Quality               int
 	FormatQuality         map[imagetype.Type]int
 	StripMetadata         bool
@@ -263,6 +265,8 @@ func Reset() {
 	PngQuantizationColors = 256
 	AvifSpeed = 8
 	JxlEffort = 4
+	WebpEffort = 4
+	WebpPreset = WebpPresetDefault
 	Quality = 80
 	FormatQuality = map[imagetype.Type]int{
 		imagetype.WEBP: 79,
@@ -496,6 +500,10 @@ func Configure() error {
 	configurators.Int(&PngQuantizationColors, "IMGPROXY_PNG_QUANTIZATION_COLORS")
 	configurators.Int(&AvifSpeed, "IMGPROXY_AVIF_SPEED")
 	configurators.Int(&JxlEffort, "IMGPROXY_JXL_EFFORT")
+	configurators.Int(&WebpEffort, "IMGPROXY_WEBP_EFFORT")
+	if err := configurators.FromMap(&WebpPreset, "IMGPROXY_WEBP_PRESET", WebpPresets); err != nil {
+		return err
+	}
 	configurators.Int(&Quality, "IMGPROXY_QUALITY")
 	if err := configurators.ImageTypesQuality(FormatQuality, "IMGPROXY_FORMAT_QUALITY"); err != nil {
 		return err
@@ -754,6 +762,12 @@ func Configure() error {
 		return fmt.Errorf("JXL effort can't be greater than 9, now - %d\n", JxlEffort)
 	}
 
+	if WebpEffort < 1 {
+		return fmt.Errorf("Webp effort should be greater than 0, now - %d\n", WebpEffort)
+	} else if WebpEffort > 6 {
+		return fmt.Errorf("Webp effort can't be greater than 9, now - %d\n", WebpEffort)
+	}
+
 	if Quality <= 0 {
 		return fmt.Errorf("Quality should be greater than 0, now - %d\n", Quality)
 	} else if Quality > 100 {

+ 12 - 0
config/configurators/configurators.go

@@ -289,3 +289,15 @@ func RegexpFromPattern(pattern string) *regexp.Regexp {
 	// It is safe to use regexp.MustCompile since the expression is always valid
 	return regexp.MustCompile(result.String())
 }
+
+func FromMap[T any](v *T, name string, m map[string]T) error {
+	if env := os.Getenv(name); len(env) > 0 {
+		if val, ok := m[env]; ok {
+			*v = val
+		} else {
+			return fmt.Errorf("Invalid %s value: %s", name, env)
+		}
+	}
+
+	return nil
+}

+ 41 - 0
config/webp_preset.go

@@ -0,0 +1,41 @@
+package config
+
+import "fmt"
+
+type WebpPresetKind int
+
+const (
+	WebpPresetDefault WebpPresetKind = iota
+	WebpPresetPhoto
+	WebpPresetPicture
+	WebpPresetDrawing
+	WebpPresetIcon
+	WebpPresetText
+)
+
+var WebpPresets = map[string]WebpPresetKind{
+	"default": WebpPresetDefault,
+	"photo":   WebpPresetPhoto,
+	"picture": WebpPresetPicture,
+	"drawing": WebpPresetDrawing,
+	"icon":    WebpPresetIcon,
+	"text":    WebpPresetText,
+}
+
+func (wp WebpPresetKind) String() string {
+	for k, v := range WebpPresets {
+		if v == wp {
+			return k
+		}
+	}
+	return ""
+}
+
+func (wp WebpPresetKind) MarshalJSON() ([]byte, error) {
+	for k, v := range WebpPresets {
+		if v == wp {
+			return []byte(fmt.Sprintf("%q", k)), nil
+		}
+	}
+	return []byte("null"), nil
+}

+ 3 - 1
vips/vips.c

@@ -1066,11 +1066,13 @@ vips_pngsave_go(VipsImage *in, void **buf, size_t *len, int interlace, int quant
 }
 
 int
-vips_webpsave_go(VipsImage *in, void **buf, size_t *len, int quality)
+vips_webpsave_go(VipsImage *in, void **buf, size_t *len, int quality, int effort, VipsForeignWebpPreset preset)
 {
   return vips_webpsave_buffer(
       in, buf, len,
       "Q", quality,
+      "effort", effort,
+      "preset", preset,
       NULL);
 }
 

+ 19 - 1
vips/vips.go

@@ -51,6 +51,8 @@ var vipsConf struct {
 	PngQuantizationColors C.int
 	AvifSpeed             C.int
 	JxlEffort             C.int
+	WebpEffort            C.int
+	WebpPreset            C.VipsForeignWebpPreset
 	PngUnlimited          C.int
 	SvgUnlimited          C.int
 }
@@ -101,9 +103,25 @@ func Init() error {
 	vipsConf.PngQuantizationColors = C.int(config.PngQuantizationColors)
 	vipsConf.AvifSpeed = C.int(config.AvifSpeed)
 	vipsConf.JxlEffort = C.int(config.JxlEffort)
+	vipsConf.WebpEffort = C.int(config.WebpEffort)
 	vipsConf.PngUnlimited = gbool(config.PngUnlimited)
 	vipsConf.SvgUnlimited = gbool(config.SvgUnlimited)
 
+	switch config.WebpPreset {
+	case config.WebpPresetPhoto:
+		vipsConf.WebpPreset = C.VIPS_FOREIGN_WEBP_PRESET_PHOTO
+	case config.WebpPresetPicture:
+		vipsConf.WebpPreset = C.VIPS_FOREIGN_WEBP_PRESET_PICTURE
+	case config.WebpPresetDrawing:
+		vipsConf.WebpPreset = C.VIPS_FOREIGN_WEBP_PRESET_DRAWING
+	case config.WebpPresetIcon:
+		vipsConf.WebpPreset = C.VIPS_FOREIGN_WEBP_PRESET_ICON
+	case config.WebpPresetText:
+		vipsConf.WebpPreset = C.VIPS_FOREIGN_WEBP_PRESET_TEXT
+	default:
+		vipsConf.WebpPreset = C.VIPS_FOREIGN_WEBP_PRESET_DEFAULT
+	}
+
 	prometheus.AddGaugeFunc(
 		"vips_memory_bytes",
 		"A gauge of the vips tracked memory usage in bytes.",
@@ -425,7 +443,7 @@ func (img *Image) Save(imgtype imagetype.Type, quality int) (*imagedata.ImageDat
 	case imagetype.PNG:
 		err = C.vips_pngsave_go(img.VipsImage, &ptr, &imgsize, vipsConf.PngInterlaced, vipsConf.PngQuantize, vipsConf.PngQuantizationColors)
 	case imagetype.WEBP:
-		err = C.vips_webpsave_go(img.VipsImage, &ptr, &imgsize, C.int(quality))
+		err = C.vips_webpsave_go(img.VipsImage, &ptr, &imgsize, C.int(quality), vipsConf.WebpEffort, vipsConf.WebpPreset)
 	case imagetype.GIF:
 		err = C.vips_gifsave_go(img.VipsImage, &ptr, &imgsize)
 	case imagetype.HEIC:

+ 1 - 1
vips/vips.h

@@ -92,7 +92,7 @@ int vips_jpegsave_go(VipsImage *in, void **buf, size_t *len, int quality, int in
 int vips_jxlsave_go(VipsImage *in, void **buf, size_t *len, int quality, int effort);
 int vips_pngsave_go(VipsImage *in, void **buf, size_t *len, int interlace, int quantize,
     int colors);
-int vips_webpsave_go(VipsImage *in, void **buf, size_t *len, int quality);
+int vips_webpsave_go(VipsImage *in, void **buf, size_t *len, int quality, int effort, VipsForeignWebpPreset preset);
 int vips_gifsave_go(VipsImage *in, void **buf, size_t *len);
 int vips_heifsave_go(VipsImage *in, void **buf, size_t *len, int quality);
 int vips_avifsave_go(VipsImage *in, void **buf, size_t *len, int quality, int speed);