fix: (Windows) Replace ICO decoder for improved icon extraction

Implemented direct use of `sergeymakinen/go-ico` decoder instead of `mat/besticon/ico`
for icon conversion. The standard `image.Decode()` and  `mat/besticon/ico` approaches
failed with certain ICO files, particularly those containing cursor data
from Windows executable resources. This change ensures more reliable
handling of various ICO format variants.
This commit is contained in:
Alexandr Stelnykovych
2025-05-14 17:49:24 +03:00
parent 84a8f755fe
commit cacf6c552a
3 changed files with 18 additions and 9 deletions

4
go.mod
View File

@@ -32,7 +32,6 @@ require (
github.com/jackc/puddle/v2 v2.2.1
github.com/lmittmann/tint v1.0.5
github.com/maruel/panicparse/v2 v2.3.1
github.com/mat/besticon v3.12.0+incompatible
github.com/mattn/go-colorable v0.1.13
github.com/mattn/go-isatty v0.0.20
github.com/miekg/dns v1.1.62
@@ -67,6 +66,8 @@ require (
zombiezen.com/go/sqlite v1.3.0
)
require github.com/sergeymakinen/go-bmp v1.0.0 // indirect
require (
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
github.com/aead/ecdh v0.2.0 // indirect
@@ -98,6 +99,7 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/satori/go.uuid v1.2.0 // indirect
github.com/seehuhn/sha256d v1.0.0 // indirect
github.com/sergeymakinen/go-ico v1.0.0-beta.0
github.com/spf13/pflag v1.0.5 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect

6
go.sum
View File

@@ -171,8 +171,6 @@ github.com/magiconair/properties v1.7.4-0.20170902060319-8d7837e64d3c/go.mod h1:
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/maruel/panicparse/v2 v2.3.1 h1:NtJavmbMn0DyzmmSStE8yUsmPZrZmudPH7kplxBinOA=
github.com/maruel/panicparse/v2 v2.3.1/go.mod h1:s3UmQB9Fm/n7n/prcD2xBGDkwXD6y2LeZnhbEXvs9Dg=
github.com/mat/besticon v3.12.0+incompatible h1:1KTD6wisfjfnX+fk9Kx/6VEZL+MAW1LhCkL9Q47H9Bg=
github.com/mat/besticon v3.12.0+incompatible/go.mod h1:mA1auQYHt6CW5e7L9HJLmqVQC8SzNk2gVwouO0AbiEU=
github.com/mattn/go-colorable v0.0.10-0.20170816031813-ad5389df28cd/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
@@ -252,6 +250,10 @@ github.com/seehuhn/fortuna v1.0.1 h1:lu9+CHsmR0bZnx5Ay646XvCSRJ8PJTi5UYJwDBX68H0
github.com/seehuhn/fortuna v1.0.1/go.mod h1:LX8ubejCnUoT/hX+1aKUtbKls2H6DRkqzkc7TdR3iis=
github.com/seehuhn/sha256d v1.0.0 h1:TXTsAuEWr02QjRm153Fnvvb6fXXDo7Bmy1FizxarGYw=
github.com/seehuhn/sha256d v1.0.0/go.mod h1:PEuxg9faClSveVuFXacQmi+NtDI/PX8bpKjtNzf2+s4=
github.com/sergeymakinen/go-bmp v1.0.0 h1:SdGTzp9WvCV0A1V0mBeaS7kQAwNLdVJbmHlqNWq0R+M=
github.com/sergeymakinen/go-bmp v1.0.0/go.mod h1:/mxlAQZRLxSvJFNIEGGLBE/m40f3ZnUifpgVDlcUIEY=
github.com/sergeymakinen/go-ico v1.0.0-beta.0 h1:m5qKH7uPKLdrygMWxbamVn+tl2HfiA3K6MFJw4GfZvQ=
github.com/sergeymakinen/go-ico v1.0.0-beta.0/go.mod h1:wQ47mTczswBO5F0NoDt7O0IXgnV4Xy3ojrroMQzyhUk=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=

View File

@@ -3,17 +3,22 @@ package binmeta
import (
"bytes"
"fmt"
"image"
_ "image/png" // Register png support for image package
"github.com/fogleman/gg"
_ "github.com/mat/besticon/ico" // Register ico support for image package
// Import the specialized ICO decoder package
// This package seems to work better than "github.com/mat/besticon/ico" with ICO files
// extracted from Windows binaries, particularly those containing cursor-related data
ico "github.com/sergeymakinen/go-ico"
)
// ConvertICOtoPNG converts a an .ico to a .png image.
func ConvertICOtoPNG(ico []byte) (png []byte, err error) {
// Decode the ICO.
icon, _, err := image.Decode(bytes.NewReader(ico))
func ConvertICOtoPNG(icoBytes []byte) (png []byte, err error) {
// Decode ICO image.
// Note: The standard approach with `image.Decode(bytes.NewReader(icoBytes))` sometimes fails
// when processing certain ICO files (particularly those with cursor data),
// as it reads initial bytes for format detection before passing the stream to the decoder.
icon, err := ico.Decode(bytes.NewReader(icoBytes))
if err != nil {
return nil, fmt.Errorf("failed to decode ICO: %w", err)
}