Skip to content
AZ Tools

ICO / CUR Inspector

Open a Windows .ico or .cur in your browser: every size inside it, PNG or BMP payloads, hotspots, the AND mask, and any broken entry.

How to use

  1. Drop a .ico or .cur file onto the box. Favicons, application icons pulled out of an .exe, and cursor files all work, and the file never leaves the tab.
  2. Read the overview for the type and the list of sizes. If the type says Cursor while the name ends in .ico, believe the type — the header decides, not the extension.
  3. Check the coverage chips for 16, 32, 48 and 256. A missing 16 usually means a browser tab is showing a mechanically shrunk large icon.
  4. Look at the findings. A payload past the end of the file, two overlapping payloads or a PNG whose IHDR disagrees with its entry are real defects, while an unusual entry order is only a matter of style.
  5. Open the BMP table for anything that is not a PNG: it gives the real height (half of biHeight), the palette, the row stride and where the AND mask starts, which is what you need if you are writing an icon reader yourself.

About this tool

Show

An icon file is not one picture but a small archive: six header bytes, then a directory of 16-byte entries, then one payload per image. This page opens that archive and shows what is actually inside — which sizes the file really contains, whether the 16, 32, 48 and 256 that Windows and browsers reach for are among them, which members are stored as PNG files and which as raw bitmaps, and how many bytes each one costs. Two details in the format trip up almost every reader, and both are handled here. A width or height byte of 0 means 256, not 0, which is why a perfectly good 256 × 256 favicon shows up as 0 × 0 in weaker tools. And the two fields after the palette size mean different things depending on the type word: colour planes and bits per pixel in an icon, the hotspot x and y in a cursor — so reading a .cur as an icon reports a nonsense bit depth, and the extension is no guide at all, since it is the type word in the header, not the file name, that decides. A BMP member gets read the whole way down: the BITMAPINFOHEADER with no file header in front of it, a biHeight that is deliberately twice the real height because the colour image and the 1-bit transparency mask are stacked in one bitmap, the palette for 1, 4 and 8-bit members, the row padding to four bytes, and the exact offset and length of the AND mask — the second place readers go wrong, because the mask has its own padding. When a member is 32-bit and really carries alpha, the mask is redundant and it is said so; when a 32-bit member has an alpha channel of nothing but zeroes, that is flagged, because such an icon disappears in anything that trusts alpha. A PNG member has its IHDR read and compared against the entry that points at it, since a directory and a payload disagreeing about the size is a common and invisible defect. Every image is also drawn, so you can see what a Windows shell would: PNG members are handed to the browser, BMP members are decoded here — palette, padding, bottom-up rows and mask — because a browser given a bare bitmap body draws the doubled height and loses the transparency entirely. The findings list names the things that are wrong rather than quietly working around them: a payload that runs past the end of the file, two payloads that overlap, two entries declaring the same size, entries out of the conventional smallest-first order, and a header that disagrees with its entry. What it cannot tell you is whether the artwork is any good at 16 pixels; that is what the previews are for.

Frequently asked questions

Why does my 256 × 256 icon show up as 0 × 0 in some tools?

Because the width and height in a directory entry are single bytes, and 256 does not fit in a byte. The format solves this by defining 0 to mean 256, so a 256 × 256 member is written with both size bytes set to zero. A reader that takes the byte at face value reports 0 × 0 — or worse, treats the member as empty and skips it. This page applies the rule, which is why the entry-bytes column shows 0, 0 next to a declared size of 256 × 256. It is also the reason no icon can hold a member larger than 256 pixels: there is nowhere in the entry to say so.

What is the difference between an ICO and a CUR file?

Structurally almost nothing: the same header, the same directory, the same payloads. Two things differ. The type word in the header is 1 for an icon and 2 for a cursor, and the two 16-bit fields that an icon uses for colour planes and bits per pixel hold the hotspot x and y in a cursor — the point inside the picture that actually does the clicking. That means reading a cursor as an icon gives you a bit depth of, say, 3, which is meaningless. The extension is unreliable in both directions, so this page reads the type word and switches the column between depth and hotspot accordingly, and it says so when the name and the header disagree.

Why is biHeight twice the height of the image?

Because a BMP member is really two bitmaps stacked in one: the colour image, called the XOR bitmap, and below it a 1-bit AND mask that says which pixels let the screen show through. The BITMAPINFOHEADER describes both at once, so its height field counts both. The real height is half of it. The mask is easy to get wrong twice over: its rows are padded to four bytes independently of the colour rows, so a 24-pixel-wide mask has 4-byte rows, not 3, and it is packed one bit per pixel with a set bit meaning transparent. This page shows the mask offset and stride so you can check that arithmetic against your own reader.

Should icon members be PNG or BMP?

Both are legal and one file can mix them, which Vista-era icons routinely do. The rule of thumb is that 256 × 256 should be PNG — a 256 bitmap with a mask costs about 256 KB per member and PNG compresses it to a fraction — and the small sizes are usually kept as BMP for compatibility, because the Windows XP shell shows nothing at all where a PNG member should be. Modern browsers read both without complaint. Since nothing in the directory records which one a payload is, a reader has to look at the first eight bytes of each payload for the PNG signature; that is exactly what the payload column here is showing.

The tool says a 32-bit member has an empty alpha channel. What breaks?

That member is invisible in anything that honours alpha, and perfectly fine in anything that uses the AND mask instead. The two mechanisms coexist: a 32-bit BMP member has an alpha byte per pixel and also carries a 1-bit mask, because the format requires the mask whether or not it is needed. Exporters that write the mask correctly but leave alpha at zero produce icons that look right in the Windows shell and vanish in a browser tab. The reverse case — real alpha and an all-zero mask — is the normal modern shape, and the tool marks the mask as redundant there.

What does it mean when the directory and the payload disagree about the size?

It means one of them is lying and the result depends on who reads the file. Windows sizes the member from the directory entry, so a 32 × 32 PNG stored under an entry that declares 48 × 48 gets stretched, softly and permanently. Some readers instead trust the payload and quietly render a different size than the one they promised. The mismatch usually comes from an editor that resized the picture and rewrote the payload without touching the directory, and it is invisible unless something reads both — which is why this page compares the IHDR and the BITMAPINFOHEADER against the entry that points at each of them.

Related tools