The evolution of the ICO file format, part 4: PNG images


We finish our tour of the evolution of the ICO file format with the introduction of PNG-compressed images in Windows Vista.

The natural way of introducing PNG support for icon images would be to allow the biCompression field of the BITMAP­INFO­HEADER to take the value BI_PNG, in which case the image would be represented not by a DIB but by a PNG. After all, that's why we have a biCompression field: For forward compatibility with future encoding systems. Wipe the dust off your hands and declare victory.

Unfortunately, it wasn't that simple. If you actually try using ICO files in this format, you'll find that a number of popular icon-authoring tools crash when asked to load a PNG-compressed icon file for editing.

The problem appeared to be that the new BI_PNG compression type appeared at a point in the parsing code where it was not prepared to handle such a failure (or the failure was never detected). The solution was to change the file format so that PNG-compressed images fail these programs' parsers at an earlier, safer step. (This is sort of the opposite of penetration testing, which keeps tweaking data to make the failure occur at a deeper, more dangerous step.)

Paradoxically, the way to be more compatible is to be less compatible.

The format of a PNG-compressed image consists simply of a PNG image, starting with the PNG file signature. The image must be in 32bpp ARGB format (known to GDI+ as Pixel­Format­32bpp­ARGB). There is no BITMAP­INFO­HEADER prefix, and no monochrome mask is present.

Since we had to break compatibility with the traditional format for ICO images, we may as well solve the problem we saw last time of people who specify an incorrect mask. With PNG-compressed images, you do not provide the mask at all; the mask is derived from the alpha channel on the fly. One fewer thing for people to get wrong.

Comments (25)
  1. Leo Davidson says:

    Nice; I didn't realise the PNG stuff was that simple. I guess it would've been obvious had I ever thought to look at a PNG icon in a hex editor.

    I'm looking forward to a future Part 5 on how the format was extended for vector images with level-of-detail branching. :) My time machine only goes at 1x speed, though. :(

  2. Andreas Rejbrand says:

    @Raymond: Thanks for a very interesting week!

  3. Brian says:

    So I assume ICONHEADER and ICONDIRENTRY are the same, and you can co-mingle PNG icons with BMP icons?  I would also assume that bColorCount is always 0 for PNG icons?

  4. Alex says:

    "The problem appeared to be that the new BI_PNG compression type appeared at a point in the parsing code where it was not prepared to handle such a failure"

    So what? Because they can't write a parser that can handle more than the field value for biCompression everybody has been using since forever, you guys have to break compatibility? Screw them, not you!

  5. Scott says:

    Well, it depends on how much better using the biCompression really is.  Both options break the icon editors, both options require writing new code in Windows to load the icons.

  6. mikeb says:

    >> Screw _them_ <<

    Once again, I don't think that Microsoft is as concerned about the developers of the icon editor as the users.  It's better for the user to get something like an 'invalid format' message when trying to open one of the PNG icon files than to have the editor crash or corrupt the file.

    And what's so wrong with a scheme that lets you just use your PNG file when you want a PNG-based icon?

    [Then the icon file wouldn't work downlevel. (Remember, icon files are a collection of images, not a single image.) -Raymond]
  7. James Schend says:

    @Alex: Also consider the security concerns. If a widely-used piece of software has an incorrect ICO parser, you could craft a ICO file that could DOS or worse a user's machine.

    The user's security and stability is more important than sticking it to bad developers.

  8. Some Guy says:

    @James Schend:

    If the parser crashes when loading unrecognized files you have a problem anyway.

    Just because the Windows developers chose not to use the obvious format doesn't mean an attacker could not exploit the buggy parser. From a security standpoint you still have the same problem, it's just not as obvious.

  9. James Schend says:

    Well, I understand your point, but if you can prevent x% of attacks by making the attacks much harder, why wouldn't you do that?

  10. prunoki says:

    For those who want to make PNG icons it is all the same, they have to learn something new. For those who own those badly written icon editors it is a better choice. I think it was a good call.

  11. Joe says:

    We use PNG files for lots of things. Too bad, Windows didn't provide full support outside of GDI+ for loading them (like from resources) or did they and I'm still too stuck in the yesterworld of XP?

  12. Alex says:

    @James Schend:

    As someone already sent, the security aspect is moot, as the flaws are still there. An attacker can just do the same thing that Raymond said MS didn't do in order to crash those editors. You do not make the attacks harder at all, as the biCompression field was already part of the ICO format. Someone just had to put something in there that those editors didn't expect.

    @prunoki:

    I am of the opinion that Windows should have broken more bad apps than they ever did. I understand that backwards compatibility is important in certain mission critical scenarios, but seriously, an ICO editor? Also, breaking a bad ICO editor with this will only affect people who actually want to use a new format. You can't possibly blame Windows for that. "Hey look, edit XZY can't open PNG ICOs, hahaa</nelson>". So what? Old software can't deal with new format, happens all the time and you just upgrade.

  13. Clipboarder Gadget says:

    What I would like to know is why LoadIcon and LoadImage still scale icons up instead of down when they dont find an exact match. Most applications only provide 16, 32, 48 and maybe 256 sizes. When DPI is set to 125% LoadIcon will scale the 16 icon to 20 and 32 to 40 and all icons look blurry. Although the developer and iconcreater didn't do anything wrong.

    You cant expect everyone to replace LoadImage/LoadIcon with LoadIconWithScaleDown (It's not even mentioned in the LoadImage page).

  14. Ian Boyd says:

    @Clipboarder Gadget: There is something somewhere is some api-set somewhere in something associated with Windows 7 where it does what you'd expect: it strives for higher-quality image by scaling down the higher quality.

    i can't remember where it was exactly, i think it was the Windows Ribbon Framwork.

    Although good luck authoring 32bpp ARGB bitmap files required for WRF; Photoshop can't do it.

  15. prunoki says:

    @Alex: when an app crashes on my windows some message comes up asking if I want to send an error report to Microsoft. Maybe they wanted to avoid that in this case, who knows? We do not know the specifics. Breaking existing things should be avoided, IMHO.

    [You're working on some project. You click "Add icon". Which do you prefer: (1) The app crashes, causing you to lose unsaved data. (2) The app says "The icon is not valid." -Raymond]
  16. WndSks says:

    @Ian Boyd: There is a free open source png2bmp converter out there that supports 32bpp ARGB and bitfield BMPs: pmt.sourceforge.net/…/index.html

  17. Leo Davidson says:

    @Ian Boyd: FWIW, Photoshop can output 32bpp ARGB BMP files, it's just not obvious how you do it. You have to convert the implicit alpha channel into an explicit channel, or something like that. I've done it and it works but I forget the exact details.

  18. Alex says:

    @prunoki:

    The error reporting dialog comes up every time a program crashes (well, many, some have their own :)). And nobody was breaking existing things, they were already broken. That's like saying hackers are breaking a program by publishing an exploit. No they don't, they just make it known.

    @Raymond:

    Sure, I'd rather see an error message in a dialog I can close and continue working. My point is: Microsoft can't fix everybody's broken programs. The developers need to fix their programs and it clearly isn't Microsoft's fault in this case. It's not like you changed the structure of the ICO format, just the contents. For now I'll keep my opinion, screw them, otherwise they'll never learn.

    [Remember who you're screwing: You're screwing the poor customer. The company that wrote the buggy program isn't suffering: They already got their money. -Raymond]
  19. Cheong says:

    Seriously, I'd think just inventing another file extension and not using ICO would be better.

    1) This is really a new format (sort of introducing multiple frame capability in PNG).

    2) Creating preview for explorer or other image management software would be easier. (less format with same extensin to detect)

    3) The users wouldn't even try to open it with broken editing software.

    A bit searching on the web turns up something called MNG. ( en.wikipedia.org/…/Multiple-image_Network_Graphics ) Although it seems to fade out because of lack of major browser native support, I'm interested to know if it was one of the candidates for the consideration.

    [You're not seeing the bigger picture. Okay, there's a new icon format for Vista-style icons. Does this mean that a program which uses Vista-style icons cannot be XP-compatible? Okay, maybe you say that they need to attach both XP-style and Vista-style icons. But you can pass only one icon directory to the LookupIconIdFromDirectory function. Does everybody have to change their code to call the new LookupIconIdFromDirectories function? Clipboard Gadget says "You can't expect everyone to replace X with Y." -Raymond]
  20. Vlasta says:

    Regarding the BI_PNG and icon editor compatibility…

    I actually downloaded the beta back in 2005 and found out about the .PNG compression and had a Vista-ready icon editor out in the public in September 2005. Others had to follow and before Vista was released, virtually every icon editor supported the new format. Well, maybe not Visual Studio, I am guessing that was the real reason ;-). Just kidding. But don't blame icon editor authors for that!

    [Too bad we didn't have access to the research project to predict the future. Hopefully once it finishes, they can invent a time machine and send the future-prediction machine back in time so we could use it. (For the record, it wasn't Visual Studio we were worried about.) Oh, and "virtually every icon editor" is not the same as "every icon editor". -Raymond]
  21. Tor Klingberg says:

    It seems some understood this article to mean that an icon file using png format is simply a png file renamed to .ico. I think what Raymond wrote is that the image part of icon file is the same as a png file. The icon file still has the ICONHEADER from part 1 of this series.

    To those saying Microsoft should have let these programs break on new icons: What would they gain by doing that? The solution Raymond described seems to have no drawbacks. Exposing bugs in programs just to spite their authors is not very professional.

    Many data formats have designed in extendability, but I find that when the time actually comes to change something, the extendability fails and one has to figure out some way to make it backwards compatible. Are there any "best practices" for how to design in extendability and forward compatibility that actually works?

  22. Kyle S. says:

    James, we shouldn't do it because it causes a moral hazard. If bad programmers know that MS will cover their butts by deliberately mis-engineering future versions of their software to work around existing bugs, then they are less likely to spend the effort getting it right the next time. They've been insulated from the risk that their program will crash. Meanwhile those who bothered to implement the spec correctly have expended their effort for nothing.

    [You've giving bad programmers too much credit. Bad programmers don't even think that far. "Hey it works, release it!" -Raymond]
  23. Alex says:

    @Raymon@Kyle S.:

    Exactly! And why should Microsoft pay the bill for those bad developers while alienating the good developers? Maybe it's economies of scale, i.e. there are more "bad ones" than "good ones"? I don't know. I guess it is a little late for MS to change from being over-compatible to the bad programmers to making a stance…

    @Vlasta

    They did the compatibility thing totally right. They had one field in the header, which changes how the rest of the file "behaves". The spec was perfectly forward compatible. The parsers some developers implemented, however, were not, as they only took the one value, which was first used for the header field into account and crashed on other values. I can imagine how that went: "Oh look at that field, biCompression, the only value I have ever seen is BI_DIB, so lets assume that it can never be anything else. That's easier for me to program anyway". There are a lot of those developers …

  24. Dean Harding says:

    I don't know why I'm surprised, but I think people are over-reacting here. I actually think the way it worked out in the end is probably *better* than if the biCompression field had been used. So rather than having "a BMP file that's compressed with the PNG compression algorithm" we have "a PNG file".

  25. 640k says:

    @Tor Klingberg:

    > The solution Raymond described seems to have no drawbacks.

    Now, some well written ico editors have to be rewritten also. Punishing well behaved developers. Thank you very much.

    [Given that BI_PNG was not a legal icon format in prior versions of Windows, the number of icon editors that had BI_PNG support (and would therefore be broken by this decision) was approximately zero. -Raymond]

Comments are closed.