ICO File Documentation
Summary
An Icon File is the Windows image format used for program, file, folder and shortcut icons. What sets it apart is that one .ico file is a container holding the same icon at several sizes (16×16, 32×32, 48×48, 256×256), so Windows can pick the sharpest one for each display. Its MIME type is image/vnd.microsoft.icon. Any modern image viewer opens it; GIMP or a favicon generator creates one from a PNG.
Technical details
| Feature | Value |
|---|---|
| Full name | Windows Icon File |
| File extension | .ico |
| MIME type | image/vnd.microsoft.icon |
| Format type | Raster image container (multiple images per file) |
| Developer | Microsoft |
| Introduced | 1985 (Windows 1.0); PNG-compressed icons since Windows Vista (2007) |
| Open standard | Partial — documented by Microsoft, proprietary origin |
| Byte order | Little-endian |
| Magic number (hex) | 00 00 01 00 (ICONDIR: reserved 0, type 1) |
| Header | 6-byte ICONDIR + 16-byte ICONDIRENTRY per image |
| Image encoding | Windows DIB bitmap (with AND/XOR mask) or embedded PNG |
| Typical sizes | 16×16, 32×32, 48×48, 256×256 |
| Colour depth | 1, 4, 8, 24 or 32-bit (32-bit adds an 8-bit alpha channel) |
| Transparency | 1-bit AND mask (DIB) or full alpha (32-bit / PNG entries) |
| Max dimension per entry | 256×256 (width/height byte 0 means 256) |
| Common use | Application icons, folder/shortcut icons, website favicons |
| Related format | Cursor .cur / .ani (same container, type 2 + hotspot) |
| Related extensions | .cur, .icns, .png, .bmp, .ani |
| Specification | learn.microsoft.com (ICO / ICONDIR) |
What is an ICO file?
An .ico file is a Windows Icon File: the small image Windows shows for a program, file, folder or shortcut. Microsoft has used the format since Windows 1.0 in 1985, and it remains the format for website favicons, the little icon in a browser tab. What makes ICO unusual among image formats is that a single file is a container: it holds the same icon rendered at several sizes and colour depths, so the operating system can display a crisp version whether the icon appears as a tiny taskbar button or a large thumbnail.
That container design is the whole point of the format, and everything technical about ICO follows from it: a directory at the front of the file lists the images it holds, and each directory entry points at a block of pixel data further down. The pixel data of any entry is either a Windows bitmap or, since Windows Vista in 2007, an embedded PNG. The sections below walk through that structure byte by byte.
The ICONDIR header: reserved, type and count
Every ICO file opens with a 6-byte structure Microsoft calls ICONDIR. It has three fields, all little-endian:
ICONDIR (6 bytes)
idReserved : uint16 = 0 // bytes 0-1: always zero
idType : uint16 = 1 // bytes 2-3: 1 = icon, 2 = cursor
idCount : uint16 // bytes 4-5: number of images in this file
The reserved field is always zero. The type field is 1 for an icon and 2 for a cursor, which is the only structural difference between an .ico and a .cur. The count field says how many images the container holds, and therefore how many directory entries follow. A favicon that ships 16×16, 32×32 and 48×48 versions has a count of 3. This is why the first four bytes of any icon file read 00 00 01 00, the signature used to detect the format.
The ICONDIRENTRY directory
Immediately after the header comes an array of ICONDIRENTRY records, one per image, each 16 bytes. This directory is what makes ICO a container: a reader parses these entries first, decides which size it wants, and jumps straight to that image’s data.
ICONDIRENTRY (16 bytes)
bWidth : uint8 // image width in px; 0 means 256
bHeight : uint8 // image height in px; 0 means 256
bColorCount : uint8 // palette entries; 0 if >=8bpp (truecolor)
bReserved : uint8 // = 0
wPlanes : uint16 // colour planes (BMP), usually 0 or 1
wBitCount : uint16 // bits per pixel
dwBytesInRes : uint32 // size of this image's data in bytes
dwImageOffset : uint32 // offset from file start to this image's data
Two details matter here. First, width and height are single bytes, so the largest value they can encode is 255; a value of 0 is defined to mean 256, which is exactly how the 256×256 icons introduced in Vista are recorded. Second, dwImageOffset is an absolute offset from the start of the file, so images can sit in any order after the directory, and dwBytesInRes gives the exact length to read. A parser never has to guess where an image begins or ends.
| Field value | Meaning |
|---|---|
bWidth / bHeight = 0 | Dimension is 256 pixels |
bColorCount = 0 | Image uses 8 bits per pixel or more (no fixed palette) |
wBitCount = 32 | Truecolour with an 8-bit alpha channel |
data starts 28 00 00 00 | A 40-byte BITMAPINFOHEADER: this entry is a DIB |
data starts 89 50 4E 47 | PNG signature: this entry is a compressed PNG |
DIB images and the AND/XOR transparency mask
For the classic small sizes, each image is stored as a Windows device-independent bitmap (DIB). Its data begins with a 40-byte BITMAPINFOHEADER, followed by an optional colour palette and the pixel rows. There is one quirk unique to icons: the header records a height that is double the real image height. That is because a DIB icon stores two stacked bitmaps: the colour image (the XOR mask) on top of a 1-bit AND mask below it. The AND mask defines transparency the old way, one bit per pixel: a set bit means “let the background show through”, a clear bit means “draw the colour pixel”. On a 32-bit icon the per-pixel alpha channel supersedes this, but the 1-bit mask is still written for compatibility with older renderers.
Like a bitmap, the pixel rows are stored bottom-up and each row is padded to a 4-byte boundary. This is the legacy path; it is compact for 16×16 and 32×32 icons but wasteful at large sizes, which is what motivated the PNG option.
PNG-compressed entries for large icons
Since Windows Vista, an individual directory entry may hold a complete PNG file instead of a DIB. A raw 256×256 32-bit bitmap is 256 KB per icon; the same image as a PNG, with DEFLATE compression and a proper alpha channel, is a fraction of that. So modern icons typically store the small sizes as DIBs and the 256×256 size as an embedded PNG. A reader tells them apart by peeking at the first bytes of the entry’s data: 28 00 00 00 (the little-endian value 40) is a BITMAPINFOHEADER and means DIB, while 89 50 4E 47 is the PNG signature. The PNG carries its own transparency, so no separate AND mask is needed for those entries.
Favicons: why /favicon.ico is multi-size
ICO is the historic format for the browser favicon. Serving one file at /favicon.ico that contains 16×16, 32×32 and 48×48 images lets a browser pick the right size for a tab, a bookmark bar or a desktop shortcut from a single request. That multi-size container behaviour is exactly what favicons need, which is why the format survived on the web long after PNG became the general image standard. Modern sites often also supply PNG and SVG icons through <link> tags, but .ico remains the widely supported default and the fallback browsers still request by convention.
ICO versus CUR: one container, two types
The Windows cursor format CUR uses the same container as ICO. The header type field is the only real divider (2 for a cursor instead of 1 for an icon), and the cursor reuses two fields of the directory entry that an icon leaves as colour planes and bit count to store the hotspot coordinates instead, the pixel within the image that marks the actual click point. Animated cursors (.ani) wrap several such cursor frames in a RIFF container. Understanding this shared layout explains why the same editors handle both formats and why a mislabelled cursor can sometimes open as an icon.
Frequently asked questions
Why does one ICO file contain several images?
By design. The ICONDIR header’s count field and the directory of ICONDIRENTRY records let one file store the same icon at 16×16, 32×32, 48×48 and 256×256. Windows reads the directory and chooses the size that matches where the icon will be drawn, so a single file stays sharp from a tiny taskbar button up to a large thumbnail.
How can an ICO entry be both bitmap and PNG?
Each directory entry is independent, so the file can mix encodings. A reader checks the first bytes of an entry’s data: 28 00 00 00 marks a 40-byte bitmap header (a DIB), while 89 50 4E 47 marks an embedded PNG. Small sizes are usually DIBs; the 256×256 size is usually a PNG because compression keeps it small.
References
- Microsoft — Icons (ICO file format, ICONDIR and ICONDIRENTRY)
- MDN — Linking favicons in HTML
- GIMP — free image editor (exports multi-size .ico)
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.