New imagedata interface (#1471)

This commit is contained in:
Victor Sokolov
2025-07-31 18:18:13 +02:00
committed by GitHub
parent dd3b430f87
commit efbea5fde5
20 changed files with 323 additions and 168 deletions

View File

@@ -251,7 +251,7 @@ func (pctx *pipelineContext) limitScale(widthToScale, heightToScale int, po *opt
func prepare(pctx *pipelineContext, img *vips.Image, po *options.ProcessingOptions, imgdata *imagedata.ImageData) error {
pctx.imgtype = imagetype.Unknown
if imgdata != nil {
pctx.imgtype = imgdata.Type
pctx.imgtype = imgdata.Format()
}
pctx.srcWidth, pctx.srcHeight, pctx.angle, pctx.flip = extractMeta(img, po.Rotate, po.AutoRotate)
@@ -266,7 +266,7 @@ func prepare(pctx *pipelineContext, img *vips.Image, po *options.ProcessingOptio
// The size of a vector image is not checked during download, yet it can be very large.
// So we should scale it down to the maximum allowed resolution
if !pctx.trimmed && imgdata != nil && imgdata.Type.IsVector() && !po.Enlarge {
if !pctx.trimmed && imgdata != nil && imgdata.Format().IsVector() && !po.Enlarge {
resolution := imath.Round((float64(img.Width()*img.Height()) * pctx.wscale * pctx.hscale))
if resolution > po.SecurityOptions.MaxSrcResolution {
scale := math.Sqrt(float64(po.SecurityOptions.MaxSrcResolution) / float64(resolution))

View File

@@ -217,7 +217,16 @@ func saveImageToFitBytes(ctx context.Context, po *options.ProcessingOptions, img
for {
imgdata, err := img.Save(po.Format, quality)
if err != nil || len(imgdata.Data) <= po.MaxBytes || quality <= 10 {
if err != nil {
return nil, err
}
size, err := imgdata.Size()
if err != nil {
return nil, err
}
if size <= po.MaxBytes || quality <= 10 {
return imgdata, err
}
imgdata.Close()
@@ -226,7 +235,7 @@ func saveImageToFitBytes(ctx context.Context, po *options.ProcessingOptions, img
return nil, err
}
delta := float64(len(imgdata.Data)) / float64(po.MaxBytes)
delta := float64(size) / float64(po.MaxBytes)
switch {
case delta > 3:
diff = 0.25
@@ -247,7 +256,7 @@ func ProcessImage(ctx context.Context, imgdata *imagedata.ImageData, po *options
animationSupport :=
po.SecurityOptions.MaxAnimationFrames > 1 &&
imgdata.Type.SupportsAnimationLoad() &&
imgdata.Format().SupportsAnimationLoad() &&
(po.Format == imagetype.Unknown || po.Format.SupportsAnimationSave())
pages := 1
@@ -258,7 +267,7 @@ func ProcessImage(ctx context.Context, imgdata *imagedata.ImageData, po *options
img := new(vips.Image)
defer img.Clear()
if po.EnforceThumbnail && imgdata.Type.SupportsThumbnail() {
if po.EnforceThumbnail && imgdata.Format().SupportsThumbnail() {
if err := img.LoadThumbnail(imgdata); err != nil {
log.Debugf("Can't load thumbnail: %s", err)
// Failed to load thumbnail, rollback to the full image
@@ -286,10 +295,10 @@ func ProcessImage(ctx context.Context, imgdata *imagedata.ImageData, po *options
po.Format = imagetype.AVIF
case po.PreferWebP:
po.Format = imagetype.WEBP
case isImageTypePreferred(imgdata.Type):
po.Format = imgdata.Type
case isImageTypePreferred(imgdata.Format()):
po.Format = imgdata.Format()
default:
po.Format = findBestFormat(imgdata.Type, animated, expectAlpha)
po.Format = findBestFormat(imgdata.Format(), animated, expectAlpha)
}
case po.EnforceJxl && !animated:
po.Format = imagetype.JXL

View File

@@ -18,7 +18,7 @@ func canScaleOnLoad(pctx *pipelineContext, imgdata *imagedata.ImageData, scale f
return false
}
if imgdata.Type.IsVector() {
if imgdata.Format().IsVector() {
return true
}
@@ -26,10 +26,10 @@ func canScaleOnLoad(pctx *pipelineContext, imgdata *imagedata.ImageData, scale f
return false
}
return imgdata.Type == imagetype.JPEG ||
imgdata.Type == imagetype.WEBP ||
imgdata.Type == imagetype.HEIC ||
imgdata.Type == imagetype.AVIF
return imgdata.Format() == imagetype.JPEG ||
imgdata.Format() == imagetype.WEBP ||
imgdata.Format() == imagetype.HEIC ||
imgdata.Format() == imagetype.AVIF
}
func calcJpegShink(shrink float64) int {
@@ -57,7 +57,7 @@ func scaleOnLoad(pctx *pipelineContext, img *vips.Image, po *options.ProcessingO
var newWidth, newHeight int
if imgdata.Type.SupportsThumbnail() {
if imgdata.Format().SupportsThumbnail() {
thumbnail := new(vips.Image)
defer thumbnail.Clear()

View File

@@ -15,7 +15,7 @@ func trim(pctx *pipelineContext, img *vips.Image, po *options.ProcessingOptions,
// The size of a vector image is not checked during download, yet it can be very large.
// So we should scale it down to the maximum allowed resolution
if imgdata != nil && imgdata.Type.IsVector() {
if imgdata != nil && imgdata.Format().IsVector() {
if resolution := img.Width() * img.Height(); resolution > po.SecurityOptions.MaxSrcResolution {
scale := math.Sqrt(float64(po.SecurityOptions.MaxSrcResolution) / float64(resolution))
if err := img.Load(imgdata, 1, scale, 1); err != nil {

View File

@@ -29,7 +29,7 @@ func prepareWatermark(wm *vips.Image, wmData *imagedata.ImageData, opts *options
po.ResizingType = options.ResizeFit
po.Dpr = 1
po.Enlarge = true
po.Format = wmData.Type
po.Format = wmData.Format()
if opts.Scale > 0 {
po.Width = imath.Max(imath.ScaleToEven(imgWidth, opts.Scale), 1)