More on Icons

Author: Joshua "Flobi" Hatfield
Updated: 2009-03-16 04:07:50AM EDT

I. Contents

  1. Contents
  2. floIcon - PHP Class for reading/writing ICO files
    1. Determining Bit count
    2. Transparency
  3. XP ICO File Format
    1. File Header
    2. Image Catalog
    3. Image Header
    4. Image Palette
    5. The XOR Map
    6. The AND Map
    7. Transparency vs. Inversion Method
  4. Update for Vista
  5. Credits

II. floIcon - PHP Class for reading/writing ICO files

floIcon makes and reads ICO files for Windows. As of version 1.1.0, Vista is supported as well as XP.

II.a. Determining Bit Count (when formatting an image for ICO format):

  • When storing an image, any alpha-transparency always dictates 32 bit.
  • The bit count is otherwise determined by a scan of the image to determine the palette.
  • The number of colors used is compared to the available bit depths to determine actual bit depth.
  • The number of colors must be less than or equal to the number of colors available at a given bit depth. E.g. An image with 17 colors would be at bit depth 8 because it is less than 256 colors (those available for 8 bit images) and greater than 16 colors (those available for 4 bit images).

II.b. Transparency (when formatting an image for ICO format):

  • Alpha-transparency always indicates status of 32 bit depth in an image.
  • True black (0,0,0) must be available in the palette for simple transparency. This may increase the color count of an image by 1 (and thereby may increase the bit depth) if there is no other use of true black in the image. (See Transparency vs. Inversion Method below.)

III. XP ICO File Format

III.a. File Header

Each ICO file begins with a 6 byte header. This tells the system: A. This is an icon file (not that there wasn't a guess in that direction from the .ico extension); and B. How many images are in the icon.

Name Size (bytes) Description
File Header: 6 Total Describes contents of the file.
Reserved 2 Value is always 0.
Type 2 Value is always 1 for icons.
Image Count 2 The number of images contained in the file.

III.b. Image Catalog

Each image has an entry in a catalog at the beginning of the file. These entries follow the header above immediately (so begin at byte offset 6). This should have enough information for the reading agent to determine which image is needed without parsing each individually. This is repeated as many times as "Image Count" above.

Name Size (bytes) Description
Entry Header: 16 Total Describes each image entry.
Width 1 Width (in pixels) of image. Value is 0 to 255. 0 indicates 256+, specify actual size in image header.
Height 1 Height (in pixels) of image. Value is 0 to 255. 0 indicates 256+, specify actual size in image header.
Color Count 1 Number of colors in image. Value equals 2 to the power of BitCount or 0 for 8+ bit images.
Reserved 1 Value is always 0.
Planes 2 Value is always 1.
Bit Count 2 Number of bits used to describe each pixel. (1, 4, 8, 24 or 32)
Size in Bytes 4 Size of the image (including the header) in bytes.
File Offset 4 Offset of the image in bytes. This is where the header starts.

Despite 0 being an invalid number for width and height, there seems to be no indication that 0 would infer 256 as a value as it does for color count. (This may not be true for Vista images.) Some icon creators are not diligent in duplicating this section with the section below and vice versa, so a check is prudent.

III.c. Image Header

Positioned at the offset indicated at the end of the entry in the catalog above, begins the image header. Mostly a duplicate of the entry itself, this is stored in a format almost identical to Windows bitmap (BMP) images. Some of the values not used here may be used in BMP images.

Name Size (bytes) Description
Image Header: 40 Total Describes each image entry.
Size of Header 4 Size of the header (excluding the header) in bytes (always 40).
Width 4 Width (in pixels) of image.
Height 4 Height (in pixels) of AND image + height of XOR image.
Planes 2 Value is always 1.
Bit Count 2 Number of bits used to describe each pixel (not including palette definitions). Value is 1, 4, 8, 24 or 32.
Size of Image 4 Size of the image (excluding the header) in bytes.
Compression 4 No compression is value 0. I have not found any documentation on using compression.
XpixelsPerM 4 I don't know. Value is 0.
YpixelsPerM 4 I don't know. Value is 0.
Colors Used 4 Number of colors in image. Value equals 2 to the power of BitCount or 0 for 8+ bit images.
Colors Important 4 I don't know. Value is 0.

III.d. Palette

If the bit count is less than 24, the palette is stored otherwise, skip this section entirely.

The number of palette entries is always 2 to the power of bit count. So, in 1 bit images, there are 2 palette entries, in 4 bit there are 16 entries, etc. This is stored as 32 bit colors one after the other as follows:

Name Size (bytes) Description
Red 1 0-255, Red Component
Green 1 0-255, Green Component
Blue 1 0-255, Blue Component
Unused 1 0. This is an unused value, probably aportioned for alpha definintion.

III.e. The XOR Map

Immediately proceeding the palette (or header if no palette is included), each pixel is stored using the number of bits specified in "Bit Count", bottom up, left to right.

If the image is 8bit or less, the bits specify the palette entry offset above (0 is the first one).

24 bit images store 3 bytes per pixel, each containing the red, green and blue components respecively.

32 bit images store 4 bytes containing red, green, blue and alpha components respectively.

No matter which bit depth is used, each row must be padded to 32 bits with 0's (this is irrelevant in 32 bit images which are already ending at the 32 bit mark).

III.f. The AND Map

The AND Map is a 1 bit pixel map stored just like the XOR map where 0 indicates off and 1 indicates on. 1 is usually used to store transparency, but see below in Transparency vs. Inversion Method why this is not always true.

Normally, the AND Map is not used in 32 bit images. However, it should still be stored. If no 24 bit image is available and the icon is used in a 24 bit environment by Windows, the 32 bit image may be converted into a 24 bit image. This is done by removing the alpha component and applying the AND map. Also, the AND map may be used for Inversion (see below) in 32 bit images

III.g. Transparency vs. Inversion Method

By placing the pixel a non-black color in the XOR map and setting the pixel on in the AND map, inversion is interpreted by Windows. This causes the background color to show through, however, inverted (to varying degrees based on the color in the XOR map). This could be very useful, I'm sure, but because PHP GD image resources do not support inversion, and neither do any of the image types supported by GD, that is not supported in floIcon.

IV. Update for Vista

The Vista update was really quite simple. Vista supports having PNG images stored in ICO files. This allows for PNG compression, as well as any other features available in the PNG format.

When the entry is a PNG image, the Image Catalog listing remains the same, but the Image Header, Palette, XOR and AND maps are all removed and replaced by a PNG file.

The PNG file format includes all of its own headers, so the dimentions in the Image Catalog are not required to read, but are preferred (if the images is smaller than 256x256) as the Image Catalog is used to find the most appropriate sized image in the icon file.

V. Credits

  • Based on the map from: http://www.daubnet.com/formats/ICO.html (cached). That map includes a fairly detailed layout of the ICO file, but it appears to be lacking in some newer information, specifically about higher bit icons.
Official PayPal Seal
 
©Copyright, blah blah blah and so forth, Flobi.com, whatever.