fix(thumbnails): decode one frame of a gif asked for as a still

imaging.Decode is DecodeAll plus SingleFrame, so a gif renamed to .png held every frame in memory; the frame limit only guards the gif output path.
This commit is contained in:
Dominik Schmidt committed 2026-10-20 14:58:31 +02:00
1 parent fa73366ff0
commit 3ff5a34ceb
1 file changed
+12 -1
@@ -70,6 +70,17 @@ func extForSourceFormatImaging(src *imagingSource) string {
}
}
// decodeStill reads the pixels of the one frame that is resized here. An
// animated gif only reaches this path when a still format was asked for, and
// imaging.Decode would hold every frame of it in memory to return the first.
func decodeStill(src *imagingSource) (image.Image, error) {
if src.format == "gif" {
return gif.Decode(bytes.NewReader(src.data))
}
return imaging.Decode(bytes.NewReader(src.data), imaging.AutoOrientation(true))
}
// resizeSourceImaging resizes with the imaging backend. The operation selects the
// resize/crop mode: fill (center-crop to the box, upscaling by default like real
// imagor's default resize), fit-in (fit within the box without cropping and
@@ -77,7 +88,7 @@ func extForSourceFormatImaging(src *imagingSource) string {
// or stretch (resize to the exact box). noUpscale caps the default fill at the
// source size, mirroring imagor's no_upscale() filter.
func resizeSourceImaging(src *imagingSource, req resizeRequest) (image.Image, error) {
img, err := imaging.Decode(bytes.NewReader(src.data), imaging.AutoOrientation(true))
img, err := decodeStill(src)
if err != nil {
return nil, err
}