home *** CD-ROM | disk | FTP | other *** search
/ Computerworld 1996 March / Computerworld_1996-03_cd.bin / idg_cd3 / ikony / programy / icnmvr22 / dlx.txt < prev    next >
Text File  |  1996-02-13  |  17KB  |  380 lines

  1. dlx.txt
  2.  
  3. Proposed Expandable Dynamic Link Library specifications:
  4.  
  5. Integrated Graphics
  6. 312 Nevada St.
  7. Northfield, MN 55057
  8. hansonr@stolaf.edu
  9.  
  10. THE BASIC IDEA
  11. --------------
  12.  
  13. Expandable DLL files (extension DLX) are dynamic link libraries
  14. that may be extended using a simple procedure at run-time. To be
  15. expandable, the library must consist of at least six sections:
  16.  
  17.   1)   a 64-byte (minimum) DOS executable header,
  18.   2)   a 64-byte New Executable header,
  19.   3)   a Resource Table containing pairs of entries: RT_GROUP and
  20.        RT_IMAGE (one of each type, 12 bytes each, must be present
  21.        for each icon),
  22.   4)   a 12-byte Resident Name Table referencing the name
  23.        "EXPNDABL",
  24.   5)   a 2-byte empty Entry Table, and
  25.   6)   a section for data referenced by the RT_GROUP and RT_IMAGE
  26.        structures.
  27.  
  28. All specifications for these sections are described below. The
  29. order is critical and must be as listed above. Any other
  30. information present (executable code, for example) must come
  31. PRIOR to the Resource Table and NOTHING except slack room ready
  32. for expansion (2x12 bytes per icon added) may appear between the
  33. Resource Table and the entry table. 
  34.  
  35. Basically, when an icon is added to the library, the Resource
  36. Table must expand by adding one new RT_GROUP name entry and one
  37. new RT_IMAGE group entry. The Resident Name Table is used as a
  38. reference to the end of the Resource Table; the Entry Table marks
  39. the end of the free space in the file. Thus, two pointers, one to
  40. the Resident Name Table, and one to the Entry Table, delineate
  41. exactly how much room is available for easy addition of icons.
  42. After that space is filled, some data pointed to by the Resource
  43. Table needs to be moved to the end of the file.  
  44.  
  45. what happens is that icons are added by:
  46.  
  47.  a)    appending the ICON data to the file (800 bytes, see below);
  48.  
  49.  b)    extending the Resource Table by 24 bytes, making room for
  50.        one new RT_GROUP and one new RT_IMAGE structure;
  51.  
  52.  c)    rewriting the Resident Name Table just after the newly
  53.        extended Resource Table; and 
  54.  
  55.  d)    updating the New Executable Header Resident Name Table
  56.        pointer.
  57.  
  58. The RT_GROUP structures come first. They take the form of Name
  59. Entries, each of which is 12 bytes and are described in detail
  60. below. As icons are added, the Resident Name Table pushes toward
  61. the Entry Table. Inspection of the New Executable Header allows a
  62. determination of how much room is available. If not enough room
  63. is present, then the following steps are taken:
  64.  
  65.  a)    the first icon (800 bytes total) after the Entry Table is
  66.        popped to the end of the line;
  67.  b)    the Entry Table (0000h) is rewritten just before the SECOND
  68.        (now first) icon;
  69.  c)    the New Executable Header is revised to indicate the new
  70.        Entry Table offset; and
  71.  d)    the Resource Table is looked through, and the appropriate
  72.        RT_GROUP and its corresponding RT_IMAGE offset references
  73.        are revised to point to the new ICON data positions in the
  74.        file;
  75.  
  76. That's a bit of work, but really it goes very fast, and since
  77. each icon is 800 bytes, that allows for 33 more icon entries in
  78. the Resource Table (2x12 bytes each) before the next icon needs
  79. to be moved. IconMover does it slightly more efficiently,
  80. calculating for a collection of icons how much room is needed,
  81. and then doing it all at once prior to adding any icons. Moving
  82. 800 bytes to the end of a file on any 80x86 machine using GET and
  83. PUT takes essentially no time whatsoever.
  84.  
  85. HOW ICON MOVER DOES IT
  86. ----------------------
  87.  
  88. The exact steps taken by Icon Mover are as follows:
  89.  
  90.  a)    determine the icons to be appended and append them, being
  91.        careful to align all data along 32-byte boundaries due the
  92.        32-byte blocking factor;
  93.  b)    concurrently write pairs of RT_GROUP and RT_IMAGE NameEntry
  94.        structures to a temporary file. (12 bytes each);
  95.  c)    do the calculation and move whatever icon data need to be
  96.        moved to the end of the file;
  97.  d)    look through the Resource Table for data entries in the
  98.        region that was moved and revise those entries;
  99.  e)    pad out the Resource Table to make room for the new entries;
  100.  f)    add the new entries from the temporary file; and, finally,
  101.  g)    rewrite the Resident Name Table (12 bytes) and the Entry
  102.        Table (2 bytes) and update the New Executable Header to
  103.        indicate their new offsets.
  104.  
  105. The key is to this arrangement is simply that the DLL file
  106. conform to the above specifications. Not all DLL files do,
  107. because there is no specific requirement for the ordering of
  108. structures in a DLL file. Some DLL files are considerably more
  109. sophisticated, of course, and must include several other
  110. structures. In principle, even these DLL files could be made
  111. expandable by careful rearranging of their component structures.
  112. Icon Mover does not attempt that, however, as I learned all this
  113. empirically with the aid of PC MAGAZINE's ICONJACK program for
  114. reference (6/27/95 issue). 
  115.  
  116. PROGRAMING DETAILS
  117. ------------------
  118.  
  119. HEADERS
  120.  
  121. It turns out that the headers can be considerably simpler than
  122. generally described. No one really needs a DLL file to say, "This
  123. program requires Microsoft Windows," for example. Thus, much of
  124. the header information can be ignored (left 00h). As far as I can
  125. tell, only the following aspects of the headers are strictly
  126. required:
  127.  
  128. offset(dec)         contents     description
  129.  
  130. 0-63                             minimal  64-byte DOS header
  131.  
  132.        0-1          "MZ"         DOS executable header signature
  133.        60-61        0040         pointer to new header (byte 64 in this
  134.                                  case)
  135.  
  136. 64-127                           minimal 64-byte "New Executable" header
  137.  
  138.        64-65        "NE"         New Executable header signature
  139.        68-69        *            Entry Table Absolute Offset
  140.        70-71        0002         Entry Table length (indicating just 2
  141.                                  bytes)
  142.        100-101      0040         Resource Table Relative Offset
  143.        102-103      *            Resident Name Table Relative Offset
  144.        126-127      030A         Windows Version expected
  145.  
  146. where contents are in hex and * means an integer (2-byte) pointer
  147. to an address offest in the file (first byte is 0 in this
  148. system). Only the Entry Table offset and the Resident Name Table
  149. offset change as icons are added to the library.
  150.  
  151. Resource Table
  152.  
  153. The Resource Table consists of a 2-byte shift count followed by
  154. blocks of TYPEENTRY and NAMEENTRY entries, followed by an
  155. ENDOFTABLE mark:
  156.  
  157.        SHIFTCOUNT
  158.        TYPEENTRY1
  159.          NAMEENTRY1a
  160.          NAMEENTRY1b
  161.          NAMEENTRY1c
  162.          etc...
  163.        TYPEENTRY2
  164.          NAMEENTRY2a
  165.          NAMEENTRY2b
  166.          NAMEENTRY2c
  167.          etc...
  168.        etc...
  169.        ENDOFTABLE
  170.  
  171. SHIFTCOUNT is an integer n, where 2^n is the "alignment factor"
  172. by which all offsets in the Resource Table must be multiplied to
  173. get the absolute file offset of an icon directory or image. In my
  174. implementation, this is 05h, indicating that all data are aligned
  175. along a 32-byte boundary. Thus, an offset of "10h" is really at
  176. file offset 16x32=512 (200h). ENDOFTABLE is a two-byte marker,
  177. 0000h. Each entry is a structure of 8 bytes (TYPEENTRY) or 12
  178. bytes (NAMEENTRY):
  179.  
  180. Type TYPEENTRY 
  181.  id As Integer            RT_GROUP = 800Eh, RT_IMAGE = 8003h
  182.  count As Integer         how many name entries
  183.  reserved As Long         000000000h
  184. End Type
  185.  
  186. Type NAMEENTRY
  187.  offset As Integer        from beginning of file, NOT relative to the
  188.                           NEH, this is the true file offset divided by
  189.                           the alignment factor, 32 in my
  190.                           implementation. 
  191.  length As Integer        32 for an icon directory entry (RT_GROUP); 
  192.                           768 for a bitmap image entry (RT_IMAGE)             
  193.  Flags As Integer         1C30h for RT_GROUP; 1C10h for RT_IMAGE
  194.  id As Integer            8000h + (index of this name entry, starting
  195.                           with 1)
  196.  handle As Integer        0000h        
  197.  usage As Integer         0000h
  198. End Type
  199.  
  200. In my version of the DLX file, this table starts at 80h (offset
  201. 128). It's pointer in the file at byte 100 (NEH offset + 36). In
  202. my DLX files, this reads "40h", reflecting that this pointer is
  203. relative to the beginning of the New Executable Header, 40h(40h +
  204. 40h = 80h). Any additional segments, data, or otherwise may
  205. appear in the DLX file between the New Executable Header and the
  206. Resource Table, however none are needed. In addition, the
  207. RT_GROUP and RT_IMAGE entries should be the last in the table if
  208. other entries exist. 
  209.  
  210.  
  211. RESIDENT NAME TABLE
  212.  
  213. The Resident Name Table is a single 12-byte entry indicating that
  214. this is an expandable DLL file:
  215.  
  216.   0          08h          length of name, eight bytes
  217.   1-8        "EXPNDABL"
  218.   9-11       00-00h       end-of-name and end-of-table marks
  219.  
  220. A pointer to this table must be in the New Executable Header at
  221. file byte 102 (NEH offset + 38). It, like the pointer to the
  222. Resource Table, is an offset relative to the beginning of the New
  223. Executable Header. In these DLX specifications, the Resident Name
  224. Table must IMMEDIATELY follow the Resource Table, and there must
  225. be only unused storage space after it.
  226.  
  227.  
  228. ENTRY TABLE
  229.  
  230. There is no true entry point for a DLX file. This table is simply
  231. two bytes, 0000h, situated just prior to the icon resources
  232. themselves (the directories and images pointed to by the NAMETYPE
  233. entries of the Resource Table). Thus, the Entry Table simply
  234. marks the beginning of the data which may be pushed to the end of
  235. the file when more room for the Resource Table is needed. An
  236. integer pointer to this table must be present at byte 68 of the
  237. file (NEH offset + 4). This pointer is an ABSOLUTE offset, not
  238. relative to the New Executable Header.
  239.  
  240.  
  241. ICON DIRECTORY
  242.  
  243. The RT_GROUP name entries point to individual Icon Directories,
  244. which themselves are 22 bytes, padded to 32 bytes by 00h to align
  245. them along a 32-byte boundary. These directories are essentially
  246. what is at the beginning of all ICO files:
  247.  
  248. 0-1          0000         reserved
  249. 2-3          0001         type, must be 1
  250. 4-5          0001         count, must be 1 for DLX; could be more in
  251.                           other DLL files
  252.  
  253. 6            20           width of image (32 bytes = 20h)
  254. 7            20           height of image
  255. 8            10           number of colors (repeated in bitmap data)
  256. 9            00           reserved
  257. 10-11        0001         number of planes (1; all icon bitmaps are
  258.                           single-plane)
  259. 12-13        0004         number of bits/pixel; this depends upon the
  260.                           number of colors, and is repeated in the
  261.                           bitmap data
  262. 14-17        00000280     size of the image (640 bytes)
  263. 18-21        000080nn     POINTER TO RESOURCE RT_IMAGE ENTRY; nn = 01,
  264.                           02, etc... 
  265. 22-31        00-00        padding to fill 32-bit boundary.
  266.  
  267.  
  268. IMAGES
  269.  
  270. Finally, the image data pointed to by the RT_IMAGE name entries
  271. must conform to standard 16-color bitmap structure, consisting of
  272. a 40-byte header, a 16-color color table (64 bytes), an XOR
  273. (color) bitmap (512 bytes), and an AND (monochrome) mask (128
  274. bytes), for a total of 744 bytes, padded to 768 bytes (32 x 24)
  275. with an additional 24 bytes:
  276.  
  277. 0-3          00000028     size of this header (40 bytes)
  278. 4-7          00000020     width of image (32 for icon)
  279. 8-11         00000040     height of image (64, because it includes an
  280.                           AND mask; for a BMP file, this is 00000020
  281. 12-13        0001         number of planes (must be 1)
  282. 14-15        0004         bits/pixel (1 for monochrome, 4 for 16-color,
  283.                           8 for 256-color, 24 for 24-bit true color.)
  284. 16-19        00000000     compression type; 0 for icons
  285. 20-23        00000280     size of image, 280h for an icon; 200h for a
  286.                           32x32 16-color bitmap (which lacks an AND
  287.                           mask)
  288. 24-27        00000000     designed X pixels per meter
  289. 28-31        00000000     designed Y pixels per meter
  290. 32-35        00000000     0 or actual length of table space in file
  291. 36-39        00000000     0 or number of colors important
  292. 40-103       whatever     color table (64 bytes, four bytes per entry)
  293. 104-615      whatever     XOR bitmap, starting with the last line of
  294.                           the table, indicating (usually) the 4-bit or
  295.                           8-bit pointer index to the color table
  296. 616-743      whatever     AND bitmask
  297. 744-767      00-00        padding
  298.  
  299. The function of the AND mask is to indicate which pixels to blank
  300. prior to writing the icon, and which to leave unchanged.
  301. Generally a 0 in the AND mask means "put my color here" and a 1
  302. in the mask means "leave this color alone." Generally a 0 in the
  303. AND mask corresponds to a pixel with color in the XOR bitmap; a 1
  304. in the AND mask best correlates with a request for black,
  305. 000000h, that is, to whichever index of the color table hold the
  306. long hex value 00000000.
  307.  
  308. Note that 744 + 22 (for the icon header) gives 766, the size of a
  309. standard icon file. Indeed, an ICO file is just the above 22-byte
  310. icon header (without the padding) followed immediately by the
  311. bitmap header, color table, XOR bitmap, and AND mask. In the case
  312. of ICO files, the image data pointer at bytes 18-21 reads
  313. "00000016", indicating that the image data follows the icon
  314. header immediately at file offset 22. Note that this AND mask,
  315. though just a string of bits 0001001000110100.... must be laid
  316. down carefully, considering the way that bits of numbers are laid
  317. down on a PC, rearranged in 16-bit chunks:
  318.  
  319. binary:      0001 0010 0011 0100  
  320. hex:           1    2    3    4        
  321.  
  322. is actually 3412h, not 1234h. Nonetheless, the AND mask DOES read
  323. left-to-right, with no rearranging.
  324.  
  325. BMP files, on the other hand, contain only the bitmap header (40
  326. bytes), color table (64 bytes), and the XOR table (512 bytes for
  327. 32x32). They have their own special 14-byte header as follows:
  328.  
  329. 0-1          "BM"         file type indicator
  330. 2-5          00000276     total file size (630 bytes for 32 x 32)
  331. 6-7          0000         reserved
  332. 8-9          0000         reserved
  333. 10-13        00000076     file offset to XOR image
  334.  
  335. Thus, a BMP file corresponding to a 32x32 16-color icon is
  336. 14+40+64+512 = 630 bytes. Note that the AND mask is lost and must
  337. be reconstructed by the user if they are making an icon from a
  338. bitmap image. This is why in Icon Mover an option exists to make
  339. one color transparent. That color is set to black in the color
  340. table, and all pixels referencing it in the AND mask are set to
  341. 1. Without this option, all icons made from bitmaps would appear
  342. with a square background rather than the spiffy "cutout" image
  343. common to icons.
  344.  
  345.  
  346. SUMMARY
  347. -------
  348.  
  349. This DLX specification allows for icons to be stored in dynamic
  350. link libraries which can be expanded to fit, read by the Program
  351. Manager, and targeted by LOADICON or EXTRACTION functions within
  352. the Windows Application Programming Interface. They are really
  353. just simplified DLL files with a certain convenient structure.
  354. The essentials, once again, are as follows:
  355.  
  356.   1)   Resident Name Table must immediately follow Resource Table
  357.        and it must contain only one entry, "EXPNDABL".
  358.   2)   Resource Table entries RT_GROUP and RT_IMAGE must be in that
  359.        order and be last in the table if others appear.
  360.   3)   Entry Table must follow Resident Name Table, with space
  361.        preferably allowed for expansion of at least a few icons.
  362.   4)   Only resource data that can be moved (i.e. referenced only
  363.        by the Resouce Table) should follow the Entry Table. 
  364.  
  365. All this really means is that if the library contains any other
  366. information other than resource data, that information must
  367. reside between the New Executable Header and the Resource Table.
  368. The 32-byte alignment factor means that offsets up to 32*2^16-32
  369. = 2,097,120 may be referenced (about 2 Mb). At 824 bytes per icon
  370. (800 bytes of aligned data + 24 bytes of unaligned Resource Table
  371. space) less overhead for the various DLL tables (64+64+6+12+2=148
  372. bytes), this allows for 2544 icons to be stored in a single DLX
  373. file. 
  374.  
  375. Perhaps there are slicker, already defined, ways of expanding a
  376. DLL file, but I don't know of any. Then again, I don't know A
  377. LOT! Give me a buzz (hansonr@stolaf.edu) if you know better how
  378. to do this. 
  379.  
  380.