ELFIconSpec

Revision 2 as of 2008-03-27 22:01:14

Clear message

Summary

As a seasoned user of the terminal, the issue of an application having an icon embedded into it is something that I didn't even notice until I started converting others to Ubuntu. I propose adding a non-obtrusive section to ELF applications that provides this functionality and can be accessed through GNOME's thumbnail capability. This idea is meant to compliment the icons provided through the package manager and take advantage of the extensibility of the ELF specification.

Many users expect applications that they've downloaded to have recognizable icons, this icon is usually something familiar from visiting the website for the program. A good example of an application that's not already included in the Ubuntu repo is "songbird", which has a large egg right next to the download link and for its Windows icon.

For a technology demo and screenshots visit [http://www.compholio.com/elficon/].

To discuss this topic please visit [http://brainstorm.ubuntu.com/idea/5744/].

Preliminary Spec

A library to handle resource files should be used in order to store images in a standardized way, this will also allow applications to store other data (such as graphics and libglade XML files). Handling the icon resource in this way results in the following architecture:

http://www.compholio.com/elficon/architecture.png

libr (sorry, librc was taken)

A proposed new library for handling adding, removing, and retrieving simple resource files from ELF binaries.

API Spec

  • int libr_clear(libr_file *handle, char *resourcename);

Remove the resource named "resourcename" from the ELF binary, the resource must exist. Returns 1 (true) on success, 0 (false) on failure.

  • void libr_close(libr_file *handle);

Close the specified file handle.

  • char *libr_list(libr_file *handle, unsigned int resourceid);

Obtain the name of a resource by id in the ELF binary, use libr_resources() to obtain the number of total resources (only libr-compatible resources are returned). Returns NULL on failure.

  • libr_file *libr_open(char *filename, libr_access_t access);

Open a file for the specified access (LIBR_READ, LIBR_WRITE, LIBR_READ_WRITE), the valid operations for the returned handle will be restricted based upon the requested access. Returns NULL on failure.

  • int libr_read(libr_file *handle, char *resourcename, char *buffer);

Read the resource named "resourcename" from the ELF binary, the resource must be saved in compliance with the binary spec. "buffer" must contain a string buffer with enough storage to hold the uncompressed contents of the resource, use libr_size() to obtain the necessary storage size. Returns 1 (true) on success, 0 (false) on failure.

  • unsigned int libr_resouces(libr_file *handle);

Returns the number of libr-compatible resources contained in the ELF binary.

  • int libr_size(libr_file *handle, char *resourcename, int *size);

Returns the uncompressed size of the specified resource ("resourcename"), use in conjuction with libr_read(). Returns 1 (true) on success, 0 (false) on failure.

  • int libr_write(libr_file *handle, char *resourcename, char *buffer, size_t size, libr_type_t *type, int overwrite);

Writes the resource named "resourcename" to the ELF binary, the resource should not exist unless "overwrite" is set to 1 (true). "buffer" must contain a string buffer with "size" bytes to write to the ELF binary. "type" specifies whether the data should be compressed by libr (LIBR_UNCOMPRESSED, LIBR_COMPRESSED). Returns 1 (true) on success, 0 (false) on failure.

Binary Spec

libelf is a good library for adding new sections to ELF files in a platform-independent way. Each resource stored in the ELF file should be named in the ELF string table using libelf and have the following header structure within the respective section:

R

E

S

<Version>

<Type>

At this time only "1" is supported for a version code, two binary "Type" values are supported:

  • 0 --- Uncompressed data follows
  • 1 --- Compressed data follows

If the data is compressed, then a 4-byte little-endian uncompressed size follows. After the header should contain zlib-compressed data, this results in the following format:

R

E

S

1

\001

<S1>

<S2>

<S3>

<S4>

...

elficon

In order to handle different icon sizes and possible access types a special section should define how all icon resources are stored. This section should be named ".icon" and contain a header, in addition to the header added by libr, with the little-endian representation of the number of entries (E*) and the "icon guid" (G*):

<E1>

<E2>

<E3>

<E4>

<G1>

<G2>

<G3>

<G4>

<G5>

<G6>

<G7>

<G8>

<G9>

<G10>

<G11>

<G12>

<G13>

<G14>

<G15>

<G16>

The "icon guid" is meant to be used by distributions to assign an icon to an application and keep that icon consistent between all ways to access the application, this field IS required even if you are not a distributor. The number of fields should be used to indicate the type and number of different icons stored in the ELF file, these fields should follow the header and should be structured as follows (S* is the entry size):

  • SVG Icon:

<S1>

<S2>

<S3>

<S4>

\000

<Icon Resource Name>

\000

  • PNG Icon:

<S1>

<S2>

<S3>

<S4>

\001

<I1>

<I2>

<I3>

<I4>

<Icon Resource Name>

\000

S* is a little-endian representation of the square icon size (16: 16x16, 32: 32x32, 48: 48x48, etc.)