icns

Easily create .icns files (Mac Icons) with this Go library or the included CLI.
Log | Files | Refs | LICENSE

commit 869b4415ed08771acef515a3da3acd185fb893d4
parent ead765cb05a444c720f1395cc1b413044622a708
Author: Andy Williams <andy@andy.xyz>
Date:   Mon, 13 Apr 2020 11:21:52 +0100

Fix parsing of some modern ICNS files (#2)

* Fix parsing to skip complete sections

TOC is variable length
Icons that are not recognised should be skipped as well
Fixes rendering of Apple Mail and other modern icons

* Don't even try to parse JPEG2000 images

* Tidy up code for skipping JPEG2000

* Clean up naming
Diffstat:
Mreader.go | 23++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/reader.go b/reader.go @@ -11,6 +11,8 @@ import ( "github.com/pkg/errors" ) +var jpeg2000header = []byte{0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20} + // Decode finds the largest icon listed in the icns file and returns it, // ignoring all other sizes. The format returned will be whatever the icon data // is, typically jpeg or png. @@ -31,17 +33,28 @@ func Decode(r io.Reader) (image.Image, error) { read += 4 switch string(next) { case "TOC ": - read += 4 + tocSize := binary.BigEndian.Uint32(data[read : read+4]) + read += tocSize-4 // size includes header and size fields continue case "icnV": read += 4 continue } + + dataSize := binary.BigEndian.Uint32(data[read : read+4]) + read += 4 + if dataSize == 0 { + continue // no content, we're not interested + } + + iconData := data[read : read+dataSize-8] + read += dataSize-8 // size includes header and size fields + if isOsType(string(next)) { - iconSize := binary.BigEndian.Uint32(data[read : read+4]) - read += 4 - iconData := data[read : read+iconSize] - read += iconSize + if bytes.Equal(iconData[:8], jpeg2000header) { + continue // skipping JPEG2000 + } + icons = append(icons, iconReader{ OsType: osTypeFromID(string(next)), r: bytes.NewBuffer(iconData),