ICO file format

BlitzMax Forums/BlitzMax Programming/ICO file format

ziggy(Posted 2008) [#1]
I'm trying to find the ICO file format specification, but all I can find is information on the header and a lot of information of the new PNG-based ico files for vista, wich are not compatible with XP.
Does anybody have the Windows XP 32-bits per pixel uncompressed file format specs for an ICO file? I have all the pix.map releated data and I want to output this data in a simple single size ICO file.


Brucey(Posted 2008) [#2]
http://www.wotsit.org/list.asp?fc=1


ziggy(Posted 2008) [#3]
Thanks brucey, but this only has information for win95-98 ico files (up to 256 colors). I need the XP format that supports 32 bits colors with alpha channel but without compression (I've already have the compressed format, but it is only compatible with Vista).


Kev(Posted 2008) [#4]
this any use?

http://www.blitzbasic.com/codearcs/codearcs.php?code=1358

*EDIT just noticed you want 32 bit, the archives example is still only 4,16,24-bit.


Bremer(Posted 2008) [#5]
Is this useful?

http://en.wikipedia.org/wiki/ICO_(icon_image_file_format)


Ked(Posted 2008) [#6]
I use MSDN for this kind of stuff.

http://msdn2.microsoft.com/en-us/library/ms997538.aspx


xlsior(Posted 2008) [#7]
Not really an .ICO, but still: Windows also supports BMP bitmap images as icons... Meaning that you can take a bitmap picture, rename it as .ICO, and use it as any other icon.

Of course that way you won't be able to store multiple dimensions inside a single file, but it can be used as an icon...


ziggy(Posted 2008) [#8]
@zawran: I've already have this information. It talks about the ICO header, the image indexing (that's working well), but when it is time to store the bitmap data, there's no info apart from the new Vista PNG compressed format. In fact, this article was my staring point.

@Ked: Thanks, but this article only covers 256 colors icons.

That's the problem I'm having. There's a lot of information about 256 icons, a lot of information about png-based icons, but no real information about 32 bits uncompressed icons with alpha channel for XP.


Brucey(Posted 2008) [#9]
Back again...

http://msdn2.microsoft.com/en-us/library/ms997636.aspx

Seems like it's a simple RGB format?


ziggy(Posted 2008) [#10]
Yes, thats for 24 bits, but somehow it is creating the alpha channel (on shadows). This is very usefull, thanks Brucey. I'll take a look to see how the alpha channel is included in this 24 bit images, I think it is stored as a separate layer. I think that with all this information, the best I can do is to make a XP icon loader so see exactly how layers are stored there, then I can make the reverse operation. Anyway if any of you have more information on how the 2 layers are stored in a ICO, please let me know it.
in the msnd documentation:
24-bit color with an 8-bit alpha channel (32-bit total)

that means that I have to store pixels on RGB format, and then a byte bank with all the alpha values?

thanks


Brucey(Posted 2008) [#11]
The article does talk about 32 bits, where it mentions the 24 + 8 bits alpha to make 32.


ziggy(Posted 2008) [#12]
Yes I see.. great, I supose the alpha layer is stored separately somehow. I'll take a deeper look, but I'm starting to see the light! :D


Brucey(Posted 2008) [#13]
I see what you mean... it's a bit vague whether you should use RGBA or RGB+A (separate block of data for alpha).

Perhaps a look at something like the FreeImage source will give you a better idea?


ziggy(Posted 2008) [#14]
As soon as I get the exact format, I'll post it here :D


ziggy(Posted 2008) [#15]
Been doing some little test. The Pixmap data of a 64x64 32 bits ico is 16936 bytes, but 64x64x4 = 16384, so we have 552 bytes of undocumented data. Any idea?

[EDIT]
Just a curious thing: could it be possible to have a DIB header(40 bytes) and a 1 bit per pixel bitmap for masking? That would do:

40 (DIB header) + (64x64)/8 = 552

Any ideas?


Brucey(Posted 2008) [#16]
Interesting snippet from freeimage :
			if(FreeImage_IsTransparent(dib)) {

				if(bit_count == 32) {
					// create the AND mask from the alpha channel

					int width_and  = WidthBytes(width);
					BYTE *and_bits = and_mask;

					// clear the mask
					memset(and_mask, 0, size_and);

					for(int y = 0; y < height; y++) {
						RGBQUAD *bits = (RGBQUAD*)FreeImage_GetScanLine(dib, y);

						for(int x = 0; x < width; x++) {
							if(bits[x].rgbReserved != 0xFF) {
								// set any transparent color to full transparency
								and_bits[x >> 3] |= (0x80 >> (x & 0x7)); 
							}
						}

						and_bits += width_and;
					}
				} 


PluginICO.cpp from FreeImage probably has all you need to understand how all the icon headers work etc.


ziggy(Posted 2008) [#17]
Ok, I see it has a 1 bit mask and it is RGB. I'll take a deeper look. thanks!


Snarkbait(Posted 2008) [#18]
does this help at all?

http://www.codeproject.com/KB/cs/IconLib.aspx


ziggy(Posted 2008) [#19]
Yes, thanks!


ziggy(Posted 2008) [#20]
This is very strange. I've got it working now:

ICO header:
2 reserved. should always be 0
2 type. 1 for icon (.ICO), 2 for cursor (.CUR) file
2 count; number of images in the file

'DIRECTORY:
1 width, should be 0 if 256 pixels
1 height, should be 0 if 256 pixels
1 colour count, should be 0 if more than 256 colours
1 reserved, should be 0
2 colour planes, should be 0 or 1
2 bits per pixel (should be 32)
4 size in bytes of the bitmap data
4 offset, bitmap data address in the file

'THEN ICO DATA HEADER:
4 HEADER SIZE
4 PIXMAP WIDTH
4 Pixmap Height
2 Color planes (must be 1)
2 the number of bits per pixel, which is the color depth of the image. Typical values are 1, 4, 8, 16, 24 and 32.
4 the compression method being used. (0-uncompressed)
4 the image size. This is the size of the raw bitmap data . should not be confused with the file size.
4 the horizontal resolution of the image. (pixel per meter, signed integer, usually 2835)
4 the vertical resolution of the image. (pixel per meter, signed integer, usually 2835)
4 the number of colors in the color palette, or 0 to default to 24 or 32 bits.
4 the number of important colors used, or 0 when every color is important; generally ignored.

RAW DATA:
The raw data is a long list of pixles (stored from 0,Height to width,0) in format BGRA
After this RAW data, a 1-bit bitmap is also RAW saved. If you save it as a back of bytes with the value 0, it will get the Alpha channel instead.

Hope it help if anybody else is interested.
Thanks to everyone.

That works! (The mumber before every field is to inform about the bytes of the data, 1=Byte, 2=16bits int, 4=32bits int, etc.)