Skip to content

Commit

Permalink
Fix parsing of some modern ICNS files (#2)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
andydotxyz authored Apr 13, 2020
1 parent ead765c commit 869b441
Showing 1 changed file with 18 additions and 5 deletions.
23 changes: 18 additions & 5 deletions reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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),
Expand Down

0 comments on commit 869b441

Please sign in to comment.