icns

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

exe.go (2279B)


      1 // Package exe reads the icons a Windows executable or DLL carries.
      2 //
      3 // A portable executable keeps its icons in the resource section as two
      4 // resource types that refer to each other: RT_GROUP_ICON holds a directory of
      5 // the sizes one icon is drawn at, and RT_ICON holds the image for each of
      6 // them. A directory and the images it names are an ico file in all but the
      7 // offsets, so this package puts them back together and hands out ico files
      8 // the ico package reads.
      9 //
     10 // A binary may carry several groups. Explorer draws the first by ordinal,
     11 // which is the one Icons returns first.
     12 package exe
     13 
     14 import (
     15 	"errors"
     16 	"fmt"
     17 )
     18 
     19 // Errors returned by the reader. They are wrapped with detail, so compare
     20 // with errors.Is.
     21 var (
     22 	// ErrNoIcons means the binary carries no icon resources.
     23 	ErrNoIcons = errors.New("no icons found")
     24 	// ErrMalformed means a resource offset or length disagrees with the
     25 	// section holding it.
     26 	ErrMalformed = errors.New("malformed resource section")
     27 )
     28 
     29 // Resource types, as the resource directory numbers them.
     30 const (
     31 	typeIcon      = 3
     32 	typeIconGroup = 14
     33 )
     34 
     35 const (
     36 	// directoryHeaderSize is the fixed part of a resource directory, before
     37 	// its entries.
     38 	directoryHeaderSize = 16
     39 	// directoryEntrySize is one entry in a resource directory.
     40 	directoryEntrySize = 8
     41 	// dataEntrySize is the leaf that points at the bytes of a resource.
     42 	dataEntrySize = 16
     43 	// groupHeaderSize is the fixed part of a group icon directory.
     44 	groupHeaderSize = 6
     45 	// groupEntrySize is one icon's row in a group icon directory. It differs
     46 	// from the ico row only in naming a resource rather than an offset.
     47 	groupEntrySize = 14
     48 	// icoEntrySize is one icon's row in an ico directory.
     49 	icoEntrySize = 16
     50 )
     51 
     52 // Group is one icon a binary carries, at every size it holds.
     53 type Group struct {
     54 	// ID is the ordinal the resource directory gives the group. Explorer
     55 	// draws the lowest.
     56 	ID uint16
     57 	// Sizes are the dimensions the directory lists, largest first.
     58 	Sizes []int
     59 
     60 	ico []byte
     61 }
     62 
     63 func (g Group) String() string {
     64 	return fmt.Sprintf("icon %d (%d sizes)", g.ID, len(g.Sizes))
     65 }
     66 
     67 // ICO returns the group as an ico file, which ico.Decode reads.
     68 //
     69 // The bytes are not copied, and must not be modified.
     70 func (g Group) ICO() []byte {
     71 	return g.ico
     72 }