Jump to content

ICO (file format)

From Wikipedia, the free encyclopedia
ICO
Filename extension
.ico
Internet media typeimage/x-icon[1] (but see below)
Uniform Type Identifier (UTI)com.microsoft.ico
Developed byMicrosoft
Type of formatGraphics file format for computer icons
Container forBMP and PNG
Extended toCUR
CUR
Filename extension
.cur
Internet media typeimage/vnd.microsoft.icon
Uniform Type Identifier (UTI)com.microsoft.cur
Developed byMicrosoft
Type of formatGraphics file format for mouse cursors
Container forBMP and PNG
Extended fromICO

The ICO file format is an image file format for computer icons in Microsoft Windows. ICO files contain one or more images at multiple sizes and color depths, such that they may be scaled appropriately. In Windows, all executables that display an icon to the user, on the desktop, in the Start Menu, or in file Explorer, must carry the icon in ICO format.

The CUR file format is an almost identical image file format for non-animated cursors in Microsoft Windows. The only differences between these two file formats are the bytes used to identify them and the addition of a hotspot in the CUR format header; the hotspot is defined as the pixel offset (in x,y coordinates) from the top-left corner of the cursor image to where the user is actually pointing the mouse.[citation needed]

The ANI file format is used for animated Windows cursors. ANI is a RIFF container; each frame within it is a complete CUR-format image and may itself contain images at multiple sizes.

History

[edit]

Icons introduced in Windows 1.0 were 32×32 pixels in size and were monochrome.[2] Support for 16 colors was introduced in Windows 3.0.[citation needed]

Win32 introduced support for storing icon images of up to 16.7 million colors (TrueColor) and up to 256×256 pixels in dimensions.[3] Windows 95 also introduced a new Device Independent Bitmap (DIB) engine.[4] However, 256 color was the default icon color depth in Windows 95. It was possible to enable 65535 color (Highcolor) icons by either modifying the Shell Icon BPP value in the registry[3][5] or by purchasing Microsoft Plus! for Windows 95. The Shell Icon Size value allows using larger icons in place of 32×32 icons and the Shell Small Icon Size value allows using custom sizes in place of 16×16 icons.[3] Thus, a single icon file could store images of any size from 1×1 pixel up to 256×256 pixels (including non-square sizes) with 2 (rarely used), 16, 256, 65535, or 16.7 million colors; but the shell could not display very large sized icons. The notification area of the Windows taskbar was limited to 16 color icons by default until Windows Me when it was updated to support high color icons.

Windows XP added support for 32-bit color (16.7 million colors plus 8-bit alpha channel transparency) icon images, thus allowing semitransparent areas like shadows, anti-aliasing, and glass-like effects to be drawn in an icon. Windows XP, by default, employs 48×48 pixel icons in Windows Explorer. Windows XP can be forced to use icons as large as 256×256 by modifying the Shell icon size value but this would cause all 32×32 icons throughout the shell to be upscaled.[3] Microsoft only recommended icon sizes up to 48×48 pixels for Windows XP.[6] Windows XP can downscale larger icons if no closer image size is available.[3]

Windows Vista added full support for 256×256-pixel 32-bit color icons,[Notes 1] as well as support for the compressed PNG format. Although compression is not required, Microsoft recommends that all 32-bit color 256×256 icons in ICO files should be stored in PNG format to reduce the overall size of the file. The Windows Vista Explorer supports smoothly scaling icons to non-standard sizes which are rendered on the fly even if an image is not present for that size in the icon file. The Windows Vista shell adds a slider for "zooming" the icon sizes in and out. With users using higher resolutions and high DPI modes, larger icon formats (such as 256×256) are recommended.[7][8]

MIME type

[edit]

While the IANA-registered MIME type for ICO files is image/vnd.microsoft.icon,[9] it was submitted to IANA in 2003 by a third party and is not recognised by Microsoft software, which uses image/x-icon or image/ico instead.[10][11] Erroneous types image/ico, image/icon, text/ico and application/ico have also been seen in use.[9]

File structure

[edit]

An ICO or CUR file is made up of an ICONDIR ("Icon directory") structure, containing an ICONDIRENTRY structure for each image in the file, followed by a contiguous block of all image bitmap data (which may be in either Windows BMP format, excluding the BITMAPFILEHEADER structure, or in PNG format, stored in its entirety).[3] It is customary practice to store the image data in the same order as the entries in the image directory.

Images with less than 32 bits of color depth follow a particular format: the image is encoded as a single image consisting of a color mask (the "XOR mask") together with an opacity mask (the "AND mask").[6][3] The XOR mask must precede the AND mask inside the bitmap data; if the image is stored in bottom-up order (which it most likely is), the XOR mask would be drawn below the AND mask. The AND mask is 1 bit per pixel, regardless of the color depth specified by the BMP header, and specifies which pixels are fully transparent(1) and which are fully opaque(0). The XOR mask conforms to the bit depth specified in the BMP header and specifies the numerical color or palette value for each pixel. Together, the AND mask and XOR mask make for a non-transparent image representing an image with 1-bit transparency; they also allow for inversion of the background. The height for the image in the ICONDIRENTRY structure of the ICO/CUR file takes on that of the intended image dimensions (after the masks are composited), whereas the height in the BMP header takes on that of the two mask images combined (before they are composited). Therefore, the masks must each be of the same dimensions, and the height specified in the BMP header must be exactly twice the height specified in the ICONDIRENTRY structure.[12]

32-bit images (including 32-bit BITMAPINFOHEADER-format BMP images[Notes 2]) are specifically a 24-bit image with the addition of an 8-bit channel for alpha compositing. Thus, in 32-bit images, the AND mask is not required, but recommended for consideration. Windows XP and higher will use a 32-bit image in less than True color mode by constructing an AND mask based on the alpha channel (if one does not reside with the image already) if no 24-bit version of the image is supplied in the ICO/CUR file. However, earlier versions of Windows interpret all pixels with 100% opacity unless an AND mask is supplied with the image. Supplying a custom AND mask will also allow for tweaking and hinting by the icon author. Even if the AND mask is not supplied, if the image is in Windows BMP format, the BMP header must still specify a doubled height.

Alpha blending is enabled only when at least one alpha byte is non-zero; if all alpha bytes are zero the frame is treated as opaque 0RGB. The colour channels use straight (non-premultiplied) alpha — R, G and B are full-intensity values, not pre-multiplied by alpha.

Even for 32-bit frames the AND mask should encode transparency correctly, with the mask bit set to 1 wherever the alpha is zero. A mask left entirely zero renders correctly when the image is drawn via alpha blending, but produces wrong results wherever the 1-bit mask is used directly, such as monochrome rendering or compositing drag images and drop-shadow silhouettes.[13]

It's important to note that in the AND mask, as for the pixel array of the bitmap, padding bytes must be appended to the end of each row in order to bring up its length to a multiple of four bytes since it's basically a (monochrome) bitmap.[3] The AND mask of an 8x8 pixels bitmap would have 1 byte of data and 3 bytes of padding(8*8*1bpp = 64 bits/8 = 8 bytes of total rows, so each row is 1 byte and 3 bytes of padding are needed), a 16x16 bitmap's AND mask would have 2 bytes of data and 2 bytes of padding, a 32x32 bitmap's AND mask would have 4 bytes of data and no padding. Note that the quantity of padding bytes needed depend on the dimensions of the bitmap and not its color depth since the AND mask is 1 bit per pixel regardless.

All values in ICO/CUR files are represented in little-endian byte order.

ICONDIR structure

[edit]
Offset
(bytes)
FieldSize
(bytes)
Description
0idReserved2Reserved. Must be 0.
2idType2Image type: 1 for ICO image, 2 for CUR image. Other values are invalid.
4idCount2Number of images in the file.
6idEntriesidCount * 16ICONDIRENTRY array. Each entry represents an image.

ICONDIRENTRY structure

[edit]
Offset
(bytes)
FieldSize
(bytes)
Description
0bWidth1Image width in pixels. Can be any number between 0 and 255. 0 means width is 256.[Notes 1]
1bHeight1Image height in pixels. Can be any number between 0 and 255. 0 means height is 256.[Notes 1]
2bColorCount1Number of colors in the color palette. For paletted depths: 2 for 1 bpp, 16 for 4 bpp; 0 for 8 bpp and above. An incorrect value affects image selection scoring for icons.
3bReserved1Reserved. Must be 0.
4wPlanes2
  • In icon format: Specifies color planes. Should be 0 or 1.[Notes 3]
  • In cursor format: Specifies the horizontal coordinates of the hotspot in number of pixels from the left.[Notes 4]
6wBitCount2
  • In icon format: Specifies bits per pixel. [Notes 5]
  • In cursor format: Specifies the vertical coordinates of the hotspot in number of pixels from the top.[Notes 4]
8dwBytesInRes4Image data size in bytes.
12dwImageOffset4Specifies the offset of BMP or PNG data from the beginning of the ICO/CUR file.

BMP format

[edit]

If an image is stored in BMP format, it must exclude the opening BITMAPFILEHEADER structure.

The height of the BMP image must be twice the height declared in the image directory. This is because the actual image data will contain two parts: the actual image immediately followed by a 1 bit mask of the same size as the image used to determine which pixels will be drawn.

The mask has to align to a DWORD (32 bits); padding bytes at the end of each row should be zero. A 0 pixel means 'the corresponding pixel in the image will be drawn' and a 1 means 'ignore this pixel'. The pixel colour is either explicit for 24 and 32 bit versions (which do not have colour tables), indexed for the other depths (1,2,4,8) in table of a four byte (BGRA) colours that follows the BITMAPINFOHEADER.

For 1 bit, the colour table has two entries: index 0 is black (#00000000) and index 1 is white (#00FFFFFF); the A channel is ignored. A pixel bit value of 0 selects black and 1 selects white.

The pixel data for 1,2,4,8 and 16 bits is packed by byte and DWORD aligned.

24-bit images are stored as B G R triples; rows are padded to a multiple of four bytes. Windows accepts 24-bit frames and internally converts them to 32 bpp; no alpha channel is preserved.

32-bit images are stored as B G R A quads.

Windows accepts only two BMP header formats for ICO/CUR frames: the standard 40-byte BITMAPINFOHEADER and the older 12-byte BITMAPCOREHEADER (OS/2 1.x format, whose color table entries are 3-byte RGBTRIPLE instead of 4-byte RGBQUAD). Extended header formats such as BITMAPV4HEADER (108 bytes) and BITMAPV5HEADER (124 bytes) are not accepted and will cause the frame to fail to load. BMP frames in ICO/CUR files should always use biSize = 40.[citation needed]

Originally, ICOs and CURs were intended to be used on monochrome displays and used the formula Output = (Existing AND Mask) XOR Image[14] but on colour screens, the cursor is composed using A channel blending and the mask is used to determine which pixels are included or excluded. In monochrome rendering the combination of AND and XOR bits determines the pixel type:

AND bitXOR bitPixel type
10Transparent (screen pixel unchanged)
11Inverted (screen pixel colour inverted)
01White
00Black

For colour cursors and icons the XOR step uses the colour bitmap instead of the 1-bit mask; transparent areas are encoded with AND=1 and opaque areas with AND=0, with the colour value stored in the colour bitmap.

PNG format

[edit]

Support for PNG frames was introduced in Windows Vista.[7] A PNG frame is a raw PNG file embedded verbatim — no BITMAPINFOHEADER, no doubled height, and no AND mask. The image format must be 32-bit RGBA; dimensions and color depth are taken directly from the PNG data.[7] Windows derives the AND mask automatically from the PNG alpha channel, so no mask need be supplied.[7]

Windows identifies a PNG frame by inspecting the first eight bytes of the image data for the standard PNG file signature (89 50 4E 47 0D 0A 1A 0A); any other leading bytes are interpreted as a BITMAPINFOHEADER-prefixed BMP frame.

Although Microsoft recommends PNG only for 256×256 images to keep file sizes down, PNG can be used at any size stored in the file.

Image selection

[edit]

When Windows loads an ICO or CUR file with multiple images, it scores each candidate entry and picks the one with the lowest score. The score combines a size component and a color depth component:

 widthScore  = |entry width  − target width|  × (2 if entry is narrower than target, else 1)
 heightScore = |entry height − target height| × (2 if entry is shorter than target, else 1)
 bppScore    = |entry bpp    − target bpp|    × 2
 totalScore  = widthScore + heightScore + bppScore

Images smaller than the requested size are penalized with a ×2 multiplier. An exact match (score 0) is returned immediately. When two entries have the same score, the one with higher color depth wins. A bWidth or bHeight value of 0 in ICONDIRENTRY is interpreted as 256 for scoring purposes. Because these fields are one byte each, they cannot represent sizes above 256; the scoring algorithm uses only the directory entry values and does not inspect the embedded image data.

For icons, color depth is derived from bColorCount when it is non-zero: values 1–3 map to 1 bpp, 4–7 to 2 bpp, 8–15 to 3 bpp, and 16 or above to 4 bpp. When bColorCount is 0, wBitCount is used directly. For cursors, bColorCount is ignored and wBitCount is always used.

Default sizes and DPI scaling

[edit]

Windows exposes the nominal icon and cursor sizes through the Win32 GetSystemMetrics function.[15] SM_CXICON/SM_CYICON report the default icon size (typically 32×32 at 96 DPI); SM_CXSMICON/SM_CYSMICON report the small icon size (typically 16×16). SM_CXCURSOR/SM_CYCURSOR report the nominal cursor size, also typically 32×32 at 96 DPI. These values are used as the default target dimensions when loading an image without an explicit size.[16]

At higher DPI settings Windows requests larger images. Both icons and cursors are always square (SM_CXICON = SM_CYICON, SM_CXCURSOR = SM_CYCURSOR). Icon sizes scale linearly with DPI; cursor sizes are rounded to a fixed set of five discrete slots. When no image at the exact target size is available, Windows applies the scoring algorithm above to select the nearest candidate and scales it to the target size.

DPI rangeScale rangeSM_CXICONSM_CXCURSOR
96–143100%–149%32–47 px32 px
144–191150%–199%48–63 px48 px
192–287200%–299%64–95 px64 px
288–383300%–399%96–127 px96 px
 384 400% 128 px128 px

The SM_CXCURSOR values above assume the default cursor size setting (pointer size = 1 in Windows Settings). The cursor size slider scales all five slots proportionally: at pointer size 2 all values double, at size 3 they triple, and so on. SM_CXICON is not affected by the cursor size setting.

Icon and cursor resources

[edit]

Icons and cursors in Portable Executable (EXE or DLL) files are organised in resources of type RT_GROUP_ICON (14), RT_GROUP_CURSOR (11), RT_ICON (3) and RT_CURSOR (1).[17]

RT_GROUP_ICON and RT_GROUP_CURSOR resources contain one NEWHEADER structure and one or more RESDIR structures which have almost the same format as corresponding ICONDIR and ICONDIRENTRY structures in ICO/CUR files. Main difference is in RESDIR that the last member of the structure contains two-byte resource identifier of the RT_ICON/RT_CURSOR instead of image offset in the file.

NEWHEADER/RESDIR structures also referred as GRPICONDIR/GRPICONDIRENTRY in many sources.[18]

NEWHEADER structure

[edit]
Offset
(bytes)
FieldSize
(bytes)
Description[19]
0Reserved2Reserved. Must be 0.
2ResType2Resource type: 1 for icon, 2 for cursor. Other values are invalid.
4ResCount2Number of RESDIR structures that immediately follow this structure.

RESDIR structure

[edit]
Offset
(bytes)
FieldSize
(bytes)
Description[20]
0ResInfo4
  • In icon format (ICONRESDIR[21]):
    • Width (1 byte) — icon image width in pixels, 0 means 256[Notes 1]
    • Height (1 byte) — icon image height in pixels, 0 means 256[Notes 1]
    • ColorCount (1 byte) — number of colors; accepted values are 2, 8 and 16; 0 means the count is deduced from Planes and BitCount
    • reserved (1 byte) — must be 0
  • In cursor format (CURSORDIR[22]):
    • Width (2 bytes) — cursor width in pixels, 0 means 256[Notes 1]
    • Height (2 bytes) — cursor height in pixels, 0 means 256[Notes 1]
4Planes2Color planes. Should be 0 or 1.[Notes 3]
6BitCount2Bits per pixel.[Notes 5]
8BytesInRes4Image data size in bytes.
12IconCursorId2Ordinal identifier of the RT_ICON or RT_CURSOR resource.


RT_ICON and RT_CURSOR resources have the same image data format as in ICO files and can store PNG images as well. Additionally, the first four bytes of RT_CURSOR resource data contain the cursor hotspot as two WORD values (x, y); these four bytes are not included in BytesInRes (in contrast to CUR files, in which the hotspot is stored in the ICONDIRENTRY structure).[23]

Icon library

[edit]

An icon library is a way to package Windows icons. It is typically a 16-bit New Executable or a 32-bit Portable Executable binary file having an .ICL extension with icon resources being the packaged icons. Windows Vista and later versions do not support viewing icons from 16-bit (New Executable) files.[24]

See also

[edit]

Notes

[edit]
  1. 1 2 3 4 5 6 7 Since Windows 95 size of an image in the ICONDIRENTRY structure might be set to zero, which means 256 pixels. Since Windows Vista, the size of an image is determined from the BITMAPINFOHEADER structure or PNG image data which technically allows storing icons with larger than 256 pixels, but such larger sizes are not recommended by Microsoft.
  2. The classic BITMAPINFOHEADER bitmap format supports storing images with 32 bits per pixel. When saved as a standalone .BMP file, "the high byte in each [pixel] is not used". However, when this same data is stored inside a ICO or CUR file, Windows XP (the first Windows version to support ICO/CUR files with more than 1 bit of transparency) and above interpret this byte as an alpha value.
  3. 1 2 Setting the color planes to 0 or 1 is treated equivalently by the operating system, but if the color planes are set higher than 1, this value should be multiplied by the bits per pixel to determine the final color depth of the image. It is unknown if the various Windows operating system versions are resilient to different color plane values.
  4. 1 2 "Windows XP icon and cursor support". Microsoft. November 18, 2005. Archived from the original on 2011-06-30. Retrieved 2023-07-03. The cursor is loaded properly at whatever color depth the cursor was authored. However, the system cannot distinguish between multiple candidates in the same cursor file or resource that differ only by their color depths. Icons, however, fully support multiple icon candidates with varying color depths.
  5. 1 2 The bits per pixel might be set to zero, but can be inferred from the other data; specifically, if the bitmap is not PNG compressed, then the bits per pixel can be calculated based on the length of the bitmap data relative to the size of the image. If the bitmap is PNG compressed, the bits per pixel are stored within the PNG data. It is unknown if the various Windows operating system versions contain logic to infer the bit depth for all possibilities if this value is set to zero.

References

[edit]
  1. "MIME Sniffing Standard". WHATWG. January 17, 2014. Archived from the original on 2014-03-27. Retrieved 2014-04-18.
  2. Fekete, Gyorgy (March 11, 2009). "Operating System Interface Design Between 1981-2009". Webdesigner Depot. Retrieved June 6, 2011.
  3. 1 2 3 4 5 6 7 8 Hornick, John (September 29, 1995). "Icons". Windows User Interface Technical Articles (MSDN). Microsoft Corporation. Retrieved June 5, 2011.
  4. "Windows 95 Architecture Components". Microsoft TechNet. Microsoft Corporation. Retrieved June 6, 2011.
  5. "Shell Icon BPP". Windows 2000 Registry Reference (Microsoft TechNet). Microsoft Corporation. Retrieved June 6, 2011.
  6. 1 2 "Creating Windows XP Icons". Windows XP Technical Articles (MSDN). Microsoft Corporation. July 2001. Retrieved 2022-11-27.
  7. 1 2 3 4 Chen, Raymond (October 22, 2010). "The evolution of the ICO file format, part 4: PNG images". The Old New Thing - Microsoft Developer Blogs. Retrieved 2022-11-27.
  8. "Icons (Design basics) - Win32 apps". learn.microsoft.com. 9 February 2021. Icons have a maximum size of 256x256 pixels, making them suitable for high-dpi (dots per inch) displays. These high-resolution icons allow for high visual quality in list views with large icons... Only a 32-bit copy of the 256x256 pixel image should be included, and only the 256x256 pixel image should be compressed to keep the file size down.
  9. 1 2 Butcher, Simon (3 Sep 2003). "image/vnd.microsoft.icon". Retrieved 3 Jan 2014.
  10. Lawrence, Eric (11 Feb 2011). "IE9 RC Minor Changes List". IEInternals. MSDN Blogs. Retrieved 20 Aug 2016. We use "image/x-icon" because that's the MIME type we've always used. Someone at some point (AFAIK, not related to Microsoft) proposed registration of the MIME type as "vnd.microsoft.icon", but Windows doesn't actually use that, it uses image/x-icon. See the second comment.
  11. Windows Imaging Component - ICO Format Overview
  12. Chen, Raymond (2010-10-19). "The evolution of the ICO file format, part 2: Now in color!". The Old New Thing. Retrieved 2022-12-30.
  13. Chen, Raymond (2010-10-21). "The evolution of the ICO file format, part 3: Alpha-blended images". The Old New Thing - Microsoft Developer Blogs.
  14. Heckel, Paul (1992). "Debunking the Software Patent Myths". MIT CSAIL.
  15. GetSystemMetrics function documentation
  16. Chen, Raymond (August 19, 2021). "What is the deal with the SM_CXCURSOR system metric?". The Old New Thing - Microsoft Developer Blogs.
  17. "Resource File Formats - Win32 apps". learn.microsoft.com. 2020-08-19. Retrieved 2023-05-22.
  18. Chen, Raymond (July 20, 2012). "The format of icon resources". The Old New Thing - Microsoft Developer Blogs. Retrieved 2023-05-20.
  19. "NEWHEADER structure". Microsoft Learn.
  20. "RESDIR structure". Microsoft Learn.
  21. "ICONRESDIR structure". Microsoft Learn.
  22. "CURSORDIR structure". Microsoft Learn.
  23. "LOCALHEADER structure - Win32 apps". learn.microsoft.com. 2020-12-11. Retrieved 2023-05-22.
  24. Chen, Raymond (May 2008). "Windows Confidential - 16-Bit Icons Are So Passé". TechNet Magazine. Retrieved November 27, 2022.
[edit]