Dirk St�cker <stoecker@epost.de>
17th February 2002
Format description of Amiga Icon Format.
This format is used by Amiga computers to display icons for each program
or project you want to access from the graphical user interface Workbench.
There are 3 different formats.
1) The OS1.x/OS2.x icons.
2) The NewIcon icon extension.
3) The OS3.5 icon extension.
A note about the used data descriptors. All elements are in Motorola byte
order (highest byte first):
APTR - a memory pointer (usually this gets a boolean meaning on disk)
BYTE - a single byte -128..127
UBYTE - an unsigned byte 0..255
WORD - a signed 16 bit value -32768..32767
UWORD - an unsigned 16 bit value 0..65535
LONG - a signed 32 bit value -2147483648..2147483647
ULONG - a unsigned 32 bit value 0..4294967295
There are lots of elements marked with ???. These are usually filled with
values, which have no effect at all. Thus they can normally be ignored.
For some values the usual contents is described.
******************************
***** OS1.x/OS2.x format *****
******************************
The OS1.x/OS2.x format is mainly an storage of the in-memory structures on
disk. This means there is many crap in that format, which may have undefined
values. This text tries to show which values are important and which not.
0x00 UWORD ic_Magic always 0xE310
0x00 UWORD ic_Version always 1
0x04 struct Gadget (described below)
0x30 UBYTE ic_Type
1 DISK a disk
2 DRAWER a directory
3 TOOL a program
4 PROJECT a project file with defined program to start
5 GARBAGE the trashcan
6 DEVICE should never appear
7 KICK a kickstart disk
8 APPICON should never appear
0x31 UBYTE ic_Pad <undefined>
0x32 APTR ic_DefaultTool <boolean>
0x36 APTR ic_ToolTypes <boolean>
0x3A LONG ic_CurrentX X position of icon in drawer/on WorkBench
0x3E LONG ic_CurrentY Y position of icon in drawer/on WorkBench
0x42 APTR ic_DrawerData <boolean>
0x46 APTR ic_ToolWindow <boolean>
0x4A LONG ic_StackSize the stack size for program execution
(values < 4096 mean 4096 is used)
This is followed by certain other data structures:
struct DrawerData if ic_DrawerData is not zero (see below)
struct Image first image
struct Image second image if ga_SelectRender not zero
(see below) in gadget structure
DefaultTool text if ic_DefaultTool not zero (format see below)
ToolTypes texts if ic_ToolTypes not zero (format see below)
ToolWindow text if ic_ToolWindow not zero (format see below)
this is an extension, which was never implemented
struct DrawerData2 if ic_DrawerData is not zero and ga_UserData
is 1 (see below)
Now a description of the sub-formats:
a) The text storage method (DefaultTool, ToolWindow and ToolTypes):
0x00 ULONG tx_Size the size of tx_Text including zero byte (tx_Zero)
0x04 ... tx_Text the plain text
.... UBYTE tx_Zero the finishing zero byte
This means the text "Hallo" will be encoded as \00\00\00\06Hallo\00.
As ToolTypes are an array of texts the encoding is preceeded by another
ULONG value containing the number of entries. But to make parsing more
interessting it is not the number as one would expect, but the number of
entries increased by one and multiplied by 4. Thus 10 entries will have
44 as count.
b) The Gadget structure:
0x00 APTR ga_Next <undefined> always 0
0x04 WORD ga_LeftEdge unused ???
0x06 WORD ga_TopEdge unused ???
0x08 WORD ga_Width the width of the gadget
0x0A WORD ga_Height the height of the gadget
0x0C UWORD ga_Flags gadget flags
bit 2 always set (image 1 is an image ;-)
bit 1 if set, we use 2 image-mode
bit 0 if set we use backfill mode, else complement mode
complement mode: gadget colors are inverted
backfill mode: like complement, but region
outside (color 0) of image is not inverted
As you see, it makes no sense having bit 0 and 1 set.
0x0E UWORD ga_Activation <undefined>
0x10 UWORD ga_GadgetType <undefined>
0x12 APTR ga_GadgetRender <boolean> unused??? always true
0x16 APTR ga_SelectRender <boolean> (true if second image present)
0x1A APTR ga_GadgetText <undefined> always 0 ???
0x1E LONG ga_MutualExclude <undefined>
0x22 APTR ga_SpecialInfo <undefined>
0x26 UWORD ga_GadgetID <undefined>
0x28 APTR ga_UserData lower 8 bits: 0 for old, 1 for icons >= OS2.x
upper 24 bits: undefined
c) The DrawerData structure:
This structure is useful for drawers and disks (but there are some
icons of other types, which still have these obsolete entries).
0x00 struct NewWindow (see below)
0x30 LONG dd_CurrentX the current X position of the drawer window
contents (this is the relative offset of the
drawer drawmap)
0x34 LONG dd_CurrentY the current Y position of the drawer window
contents
d) The NewWindow structure used by DrawerData:
0x00 WORD nw_LeftEdge left edge distance of window
0x02 WORD nw_TopEdge top edge distance of widndow
0x04 WORD nw_Width the width of the window (outer width)
0x06 WORD nw_Height the height of the window (outer height)
0x08 UBYTE nw_DetailPen always 255 ???
0x09 UBYTE nw_BlockPen always 255 ???
0x0A ULONG nw_IDCMPFlags <undefined>
0x0E ULONG nw_Flags <undefined>
0x12 APTR nw_FirstGadget <undefined>
0x16 APTR nw_CheckMark <undefined>
0x1A APTR nw_Title <undefined>
0x1E APTR nw_Screen <undefined>
0x22 APTR nw_BitMap <undefined>
0x26 WORD nw_MinWidth <undefined> often 94, minimum window width
0x28 WORD nw_MinHeight <undefined> often 65, minimum window height
0x2A UWORD nw_MaxWidth <undefined> often 0xFFFF, maximum window width
0x2C UWORD nw_MaxHeight <undefined> often 0xFFFF, maximum window width
0x2E UWORD nw_Type <undefined>
e) The DrawerData2 structure for OS2.x drawers:
0x00 ULONG dd_Flags flags for drawer display
value 0 handle viewmode like parent drawer current
setting (OS1.x compatibility mode)
bit 0 view icons
bit 1 view all files (bit 0 maybe set or unset
with this)
0x04 UWORD dd_ViewModes viewmodes of drawer display
value 0 show icons (OS1.x compatibility mode)
value 1 show icons
value 2 show sorted by name
value 3 show sorted by date
value 4 show sorted by size
value 5 show sorted by type
f) And now the last element, the Image structure:
0x00 WORD im_LeftEdge always 0 ???
0x00 WORD im_TopEdge always 0 ???
0x04 WORD im_Width the width of the image
0x06 WORD im_Height the height of the image
0x08 WORD im_Depth the image bitmap depth
0x0A APTR im_ImageData <boolean> always true ???
0x0E UBYTE im_PlanePick foreground color register index
0x0F UBYTE im_PlaneOnOff background color register index
0x10 APTR im_Next always 0 ???
This is followed by the image data in planar mode. The width of the
image is always rounded to next 16bit boundary.
******************************
***** NewIcon extension ******
******************************
As the original format is very limited when using more than the 4 or 8 default
colors and also when using different palette sets than the default, there have
been ideas how to circumvent this. A Shareware author invented NewIcons
format, which uses the ToolTypes to store image data, as expanding the original
format very surely would haven broken compatibility.
The NewIcons stuff usually starts with following 2 ToolTypes text (text inside
of the "" only):
" "
"*** DON'T EDIT THE FOLLOWING LINES!! ***"
Aftwerwards the image data is encoded as ASCII. The lines for first image
always start with "IM1=". If present the second image starts with "IM2=".
The first line of each image set contains the image information and the
palette.
Example: "IM1=B}}!'��5(3%;ll����T�S9`�"
0x00 UBYTE ni_Transparency
"B" transparency on
"C" transparency off
0x01 UBYTE ni_Width image width + 0x21 - "}" means width 92
0x02 UBYTE ni_Height image height + 0x21 - "}" means height 92
0x03 UWORD ni_Colors ASCII coded number of palette entries:
entries are: ((buf[3]-0x21)<<6)+(buf[4]-0x21)
"!'" means 6 entries
Afterwards the encoded palette is stored. Each element has 8 bit and colors
are stored in order red, green, blue. The encoded format is described below.
The ni_Width and ni_Height maximum values are 93. The maximum color value
is theoretically 255. I have seen images with at least 257 stored colors
(but less than 256 used).
The following lines contain the image data encoded with the same system as
the palette. The number of bits used to encode an entry depends of the number
of colors (6 colors f.e. need 3 bit). The lines have maximum 127 bytes
including the "IM1=" or "IM2=" header. Thus including the zero byte, the
string will be 128 byte.
En/Decoding algorithm:
Each byte encodes 7bit (except the RLE bytes)
Bytes 0x20 to 0x6F represent 7bit value 0x00 to 0x4F
Bytes 0xA1 to 0xD0 represent 7bit value 0x50 to 0x7F
Bytes 0xD1 to 0xFF are RLE bytes:
0xD1 represents 1*7 zero bits,
0xD2 represents 2*7 zero bits and the last value
0xFF represents 47*7 zero bits.
Opposite to the original icon format, the NewIcons format uses chunky modus
to store the image data.
The encoding for images and palette stops at the string boundary (127 bytes)
with buffer flush (and adding pad bits) and is restarted with next line.
******************************
****** OS3.5 extension *******
******************************
The OS3.5 format introduces nearly the same information as in NewIcons, but
in a more usable format. The tooltypes are no longer misused, but a new data
block is appended at the end of the icon file. This data block is in IFF
format.
It consists of the standard header
0x00 UBYTE[4] ic_Header set to "FORM"
0x04 ULONG ic_Size size [excluding the first 8 bytes!]
0x08 UBYTE[4] ic_Identifier set to "ICON"
Now Chunks of different data follow. Each chunk consists of 8 header bytes
and the data bytes. If the size in header is uneven, then it is automatically
paddind with 1 byte at the end.
Currently 3 chunks are used with following data. Note that IFF generally
allows expansion and chunk reordering, so do not rely on any current size
information or chunk order, but skip unknown data based on the size
information stored in file.
1)
0x00 UBYTE[4] fc_Header set to "FACE"
0x04 ULONG fc_Size size [excluding the first 8 bytes!]
0x08 UBYTE fc_Width icon width subtracted by 1
0x09 UBYTE fc_Height icon height subtracted by 1
0x0A UBYTE fc_Flags flags
bit 0 icon is frameless
0x0B UBYTE fc_Aspect image aspect ratio:
upper 4 bits x aspect
lower 4 bits y aspect
0x0C UWORD fc_MaxPalBytes maximum number of bytes used in image palettes
subtracted by 1 (i.e. if palette 1 has 17 and
palette 2 has 45 entries, then this is 45)
2) Now 2 chunks of this type may come, where first chunk is image 1
and second chunk is image 2.
0x00 UBYTE[4] im_Header set to "IMAG"
0x04 ULONG im_Size size [excluding the first 8 bytes!]
0x08 UBYTE im_Transparent number of the transparent color
0x09 UBYTE im_NumColors number of colors subtracted by 1
0x0A UBYTE im_Flags
bit 0 there exists a transparent color
bit 1 a palette data is attached (NOTE, that first
image always needs palette data, whereas the
second one can reuse the first palette.)
0x0B UBYTE im_ImageFormat storage format of image data
value 0 uncompressed
value 1 run-length compressed
0x0C UBYTE im_PalFormat storage format of palette data (same as above)
0x0D UBYTE im_Depth the number of bits used to store a pixel
0x0E UWORD im_ImageSize number of bytes used to store image (subtracted
by 1)
0x10 UWORD im_PalSize number of bytes used to store palette
(subtracted by 1)
0x12 UBYTE[...] the image data
.... UBYTE[...] the palette data (if existing)
Now about the run-length compression. This is equal to the run-length method
in IFF-ILBM format: The input data is seen as a bit-stream, where each entry
has im_Depth bits for image or 8 bits for palette. First comes an 8 bit RLE
block with following meaning:
0x00 .. 0x7F copy the next n entries as they are, where n is "RLE-value"+1
0x80 ignore this, do nothing
0x81 .. 0xFF produce the next entry n times, where n is 256-"RLE-value"+1
(if using signed chars n is "RLE-value"+1)
In uncompressed mode, each byte represents one pixel (even if lower depth is
used).
********************************