If you ever need to maniipulate the bits and the information in an Icon file you will need to go beyond the standard loading and saving functions available in Delphi. As well Delphi's saving and loading functions for Icons seems to only save and load small 16 by 16, 16 color Icons, which then display terribly as 32 by 32 icons as you would expect. The code associated with this page demos opening and viewing Icons by loading them directly from disk, and was written in preparation for the writing of code to directly save an Icon, bypassing Delphi. (The Windows API also does not include routines to save Icons. Some of the puzzles you have to solve to accomplish this are not trivial, and apparently its supposed to be that way - why are you trying to save someone else's icon, they must have thought.)
YOu can download the code associated with this article as a Delphi 3 / Delphi 5 project here ... icon_file.zip (17 KB) or you can view the source code as a text file by following these links ... icon_file_d3.txt Delphi 3 version or icon_file_d5.txt Delphi 5 version
The following page describes the Icon file format and includes code for directly reading an icon file from disk. An Icon file begins with a File Header in the following format...Since an icon file can have more than one icon present, the total number of icons in the file is indicated by the value idCount.
TIconHeader = record
idReserved: Word; {always 0}
idType: Word; {always 1, identifies file as Icon file}
idCount: Word; {total number of icon pics in file}
end;
Immediately after the header follows idCount number of Icon Directory Records which describe each of the icons in the file.
TIconDirEntry = record
bWidth: Byte; {ie: 16 or 32}
bHeight: Byte; {ie: 16 or 32}
bColorCount: Byte; {number of entires in pallette table below}
bReserved: Byte; { not used = 0}
wPlanes: Word; { not used = 0}
wBitCount: Word; { not used = 0}
dwBytesInRes: Longint; {total number bytes in images including pallette data XOR, AND and bitmap info header}
dwImageOffset: Longint; {pos of image as offset from the beginning of file}
end;
After the Directory entries is the actual image data for each icon. The data is arranged as a BitMapInfoHeader, palette data, and the Color image pixel data (the XOR Mask) and the Black and White pixel data (the AND mask). In order to display an icon 'transparently' the AND mask is applied to the screen using the AND operation and the XOR mask is applied using the exclusive or operation. The code accompanying this page displays both masks in Image objects, and you can see that the color image is surrounded by Black while the AND mask (monochrome black and white) is black where the color image is present and then white outside the image. Black is encoded as color zero and white as a complete set of binary ones, so when the AND mask is applied to the screen using the AND operation, where the image is black, the screen pixels are excluded (1 and 0 = 0). When the color Mask is then applied using the exclusive or operation, only those places where the screen has been excluded (made zero by the AND operation described above) will the pixels of the color XOR map be applied to the screen (an exclusive or operation, only one or the other but not both).
For this reason the Icon includes two bitmaps, one larger bitmap (in color) and one smaller bitmap in Black and white (one bit per pixel).
The Bitmap info Header is found at the start of each icon in the icon file (although, I have found that most icon files contain only one 32 by 32 16 color icon, and a smaller icon is created by the system by compressing the data of this larger icon). The Bitmap info header for an icon file is identical to a standard Bitmap info header with the difference being that the 'height' field is doubled (the height of the XOR mask plus the height of the AND mask). The size image, however, refers to the color bitmap. Since icons are so small, compression is not used, and most icons are 4 bit/16 color although some are 8 bit/256 color and I have seen one icon that was 24 bit, but this was probably an anomaly.
TBitmapInfoHeader = record
biSize: Longint; {size of tbitmapinfoheader = 40}
biWidth: Longint; {bitmap width}
biHeight: Longint; (height of bitmap)
biPlanes: Word; {always 1}
biBitCount: Word; {number color bits 4 = 16 colors, 8 = 256 pixel is a byte}
biCompression: Longint; {compression used, 0 }
biSizeImage: Longint; ( size of the pixel data)
biXPelsPerMeter: Longint; {not used, 0 }
biYPelsPerMeter: Longint; {not used, 0 }
biClrUsed: Longint; {number of colors used, set to 0 }
biClrImportant: Longint; {important colors, set to 0 }
end;
The Bit Map info header is followed by the palette data in the form of RGB quads, as described on the page on the Bitmap file format. The number of bytes in the palette entries will be IconDirEntry.bColorCount * 4.
After the palette entries comes the bit data for the color Bitmap, followed by the Bit data for the Black and white 1 bit AND bitmap. If more icons follow this will be followed by a Bitmap info header, a palette, a color bit map, a black and white bit map, etc.
A few points to discuss concerning the source code accompanying this page. Windows API functions will only return icons that are deemed suitable for the display. When you actually open an icon file yourself, and find that it includes multiple icons, and then use the API, it will report that only 1 icon was found. Some icon files do not seem to conform to specs. For example the 'Windows Update' Icon file contains 6 icons. Three can be read fine. Two do not seem to have an AND mask in the location that it is supposed to be in, and a thorough search of the area did not turn up an AND mask. The last icon in the file returns a suitable color and black and white bitmap, but then comes back from the API strangely colored. The RGB quad bytes for a bitmap must be red in byte by byte in the order Blue, Green, Red or the Bitmap will display with its colors reversed. The situation with icons is less clear to me at the moment because icons are returned with no Palette (the handle is zero) and sometimes the API seems to ignore the palette altogether, making it more difficult to determine the exact order of the RGB quads in an icon file. Delphi 5 includes dynamic arrays. This crashes Delphi 3 and so the arrays have been made static. If you know something more about Delphi 3 you might want to modify the code at this point. I have also achieved weird results when using untyped binary files to read and write to record structures (something to do with four byte boundaries and so on) and have made some fruitless searches on the net for more info. For this reason temporary variables are read from disk and then inserted into the records. If you know more about this matter you can also modify the code at this point.
A Unified Field Theory
![]()
The Unified Field Theory
is also available as a zip file -> unified.zip
Introduction :The Pioneer Effect and the New Physics. A brief description of the new physics required to explain the 'Pioneer Effect', which is the constant deceleration of space craft as they fly through space.

