commit 56bd4e8ba5a555d192d0bad277c3a736c9906991
parent a0554fe76cb70ad063a045dcbe2428a7f0c38dbd
Author: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Date: Fri, 18 Sep 2026 16:09:32 -0400
cmd/shell-extension: decode only the icon it needs
Explorer asks for one thumbnail at a time, and the provider decoded every
icon in the file to return one of them. Files now carry more elements than
they did, so the waste grew with them.
Diffstat:
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/cmd/shell-extension/internal/provider/provider.go b/cmd/shell-extension/internal/provider/provider.go
@@ -198,16 +198,31 @@ func Thumbnail(r io.Reader, cx int) (*image.RGBA, error) {
if cx <= 0 {
return nil, fmt.Errorf("invalid thumbnail size %d", cx)
}
- images, err := icns.DecodeAll(r) // Sorted largest first.
+ d, err := icns.NewDecoder(r)
if err != nil {
return nil, err
}
- chosen := images[0]
- for _, img := range images {
- if side(img) < cx {
+ // The icons arrive largest first, so the last one still at least cx wide
+ // is the smallest that does not need upscaling. Only that one is decoded.
+ var (
+ best icns.Entry
+ found bool
+ )
+ for _, icon := range d.Icons() {
+ if icon.ImageFormat == icns.ImageFormatJPEG2000 {
+ continue
+ }
+ if found && int(icon.Size) < cx {
break
}
- chosen = img
+ best, found = icon, true
+ }
+ if !found {
+ return nil, fmt.Errorf("no icon in a format this build can decode")
+ }
+ chosen, err := best.Decode()
+ if err != nil {
+ return nil, err
}
// Normalise to premultiplied RGBA, which is what a GDI ARGB bitmap
// wants, shrinking the icon to fit the cx square on the way if needed.