home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / 3_1DOCS.DMS / in.adf / tutorials.lha / tutorials / ILBM_and_AA < prev    next >
Encoding:
Text File  |  1993-11-04  |  16.4 KB  |  406 lines

  1.  
  2. ILBM Files: V39 and AA Support Issues
  3. =====================================
  4. Carolyn Scheppner - Technical Manager - CATS U.S.
  5.  
  6. (c) Copyright 1992 Commodore-Amiga, Inc.  All Rights Reserved
  7.  
  8.  
  9. For compatibility with and support of enhanced Amiga graphics
  10. capabilities, both the short-term and long-term possibilities, you must
  11. modify your software to remove any built-in limitations which would
  12. prevent you from growing WITH the Amiga.
  13.  
  14.  
  15. I. Get RID of Hardcoded Limits, Write Software that Adapts
  16.  
  17. Many of the Amiga graphics software packages currently on the market
  18. are hardcoded like the old "DF0: DH0:" file requesters.
  19.  
  20. Such hardcoded graphics application software limits include:
  21.  
  22. - offering a fixed set of display modes or sizes
  23. - offering a fixed range of depths or sizes for certain display modes
  24. - loading or handling a maximum of 32 colors
  25. - Dealing with color guns as 4-bit values
  26.  
  27.  
  28. The first thing you need to think about when upgrading your application
  29. for V39, is NOT to upgrade it for V39.  You must upgrade your software
  30. so that it can adapt to arbitrary display modes, depths, and sizes.
  31.  
  32. If you offer different display modes, do not arbitrarily restrict
  33. the modes that you offer.  If 8-bitplane hires, or hires HAM, are
  34. supported by a new chip set, and your software restricts a user to
  35. 5-bitplane hires and lores HAM, then your software will be obsolete.
  36.  
  37. Rewrite your software to use features such as the 2.1 display mode
  38. requester.  Make sure that your software can adapt to larger palettes.
  39. Handle R G and B values internally as at least 8-bits, not 4.
  40.  
  41.  
  42.  
  43. II. Proper IFF ILBM Support
  44.  
  45. When loading, saving, and processing ILBM files, care must be taken
  46. to properly support the current and future graphics capabiities of
  47. the Amiga.  Hardcoded limits and assumptions often exist in ILBM
  48. handling code.  The NewIFF39 code modules attempt to properly
  49. implement all of the following concepts in a backward (and hopefully
  50. forward) compatible manner.
  51.  
  52.  
  53. A. Proper ILBM.CAMG Chunk
  54.    ======================
  55.  
  56. 1. Saving
  57.  
  58. If running under V36 or higher, save a 32-bit mode id in the CAMG ULONG.
  59. Some of these modes have all zeros in the upper word and are classic
  60. Amiga viewmodes.  Others are more complex but generally provide a
  61. good bit pattern in the low word to allow reasonable results if displayed
  62. with an old viewer.  You may wish to let your user decide if a different
  63. mode id should be saved.  For example, a user may prefer to work in DBLNTSC
  64. but need to save his images as plain HIRES LACE for genlocking.
  65. See V39 graphics/modeid.h for current modes.
  66. Use the 2.1 ASL screen mode requester or the display database if you wish
  67. to offer only all modes available on the user's system.
  68. Use ULONG modeid = GetVPModeID(viewport) if you are saving
  69. the mode id of a display.
  70.  
  71. 2. Loading
  72.  
  73. Support reading and using full 32-bit modeid's from CAMG, with some
  74. screening for bad ID's, and fallback code if ModeNotAvailable().
  75. Screening is required because there are some CAMG's out there with
  76. garbage in the upper word.  See sample "getcamg" code at end.
  77. Under V39 or higher, the new BestModeIDA() graphics function can
  78. be used to query for a suitable and available replacement mode
  79. when an ILBM CAMG mode is not available.  Stop looking at the
  80. bits of graphics mode id's.  See the NewIFF39 code modules for example
  81. usage of BestModeIDA().
  82.  
  83.  
  84.  
  85. B. Proper ILBM.BMHD X and Y aspect
  86.    ===============================
  87.  
  88. 1. Saving
  89.  
  90. Use the display database in a simple manner to get the correct
  91. x and y aspect values for the ILBM.BMHD.
  92. See the "getaspect" code below.  This code gets the correct
  93. aspect ratio for any viewport modeid from the display
  94. database.  If running under < V36, it falls back to
  95. updated 2.0-compatible aspect values for old modes.
  96.  
  97. 2. Loading
  98.  
  99. Perhaps you can start to expect reasonable information
  100. in the ILBM.BMHD x and y aspect fields.
  101.  
  102.  
  103.  
  104. C. Proper 8-bit-per-gun ILBM.CMAP
  105.    ==============================
  106.  
  107. Problem: the CMAPs of many ILBMs contain only 4-bits-per-gun of of R,
  108. G, and B, each left justified in a CMAP byte - for example, white saved
  109. as F0 F0 F0 rather than FF FF FF.  This made no difference when Amigas
  110. could only display 4-bits-per-gun of color (i.e. 4096 different colors)
  111. since only the upper 4 bits of each CMAP byte were used when setting
  112. colors, and for example, RGB of $F F F, whether stored as F0 F0 F0
  113. or FF FF FF, was 4-bit white.
  114. But AA Amigas can display 8-bits-per-gun of color (16,000,000 different
  115. colors), and F0 F0 F0 is not quite white - FF FF FF is.
  116. To properly display 8-bits of color from an ILBM whose CMAP contains
  117. only 4-bits of color information per gun, you must know to scale the 4 bits
  118. to 8 bits.  But in most ILBM's there is no flag to tell you
  119. whether the CMAP contains 4 left-justified or 8 significant bits per gun.
  120.  
  121. Here are tips on saving and loading 8-bit-per-gun colors, and some
  122. strategies and a new flag bit for recognizing and
  123. dealing with both 4-bit and 8-bit CMAP colors.
  124.  
  125. 1. Saving
  126.  
  127. Either always save CMAPs with 8 significant bits-per-gun, or
  128. save 8-bits-per-gun by default and offer a 4-bit palette save option
  129. (for compatibility with some products which may contain containing
  130. broken handcrafted CMAP color handling code).  When saving
  131. from a 4-bit-per-gun source, do NOT left justify each 4-bit gun in
  132. the CMAP R, G, and B bytes, but rather SCALE each 4-bit value to 8 bits
  133. by duplicating the 4-bit value in the upper and lower nibble of its
  134. R, G, or B CMAP byte (e.g. save white as $FF FF FF, etc.).  When saving
  135. under V39 or higher, if you must extract the colors from a display, use
  136. the new 32-bit graphics color getting function GetRGB32().  Do not read
  137. a ColorMap's ColorTable directly.  Save the 8 most significant bits of
  138. each gun in the CMAP.
  139.  
  140. IMPORTANT:  A new advisory BMHD flag, BMHDF_CMAPOK, has been
  141. defined to indicate that an ILBM contains an 8 bit significant
  142. CMAP, not an old 4-bit left-justified CMAP.  The advisory flag is
  143. the high bit (1 << 7) of the BMHD.Flags byte (formerly named BMHD.Pad1 or
  144. BMHD.Reserved1).  Whenever you save an 8-bit-significant CMAP
  145. (either 4 bits scaled to 8 bits or true 8 bits), we suggest that you set
  146. this flag bit in your BMHD.Flags to advise aware loaders
  147. that your CMAP values are definitely not 4-bit shifted values
  148. and do not need scaling to 8 bits.
  149.  
  150. #define BMHDB_CMAPOK    7
  151. #define BMHDF_CMAPOK    (1 << BMHDB_CMAPOK)
  152.  
  153.  
  154. 2. Loading
  155.  
  156. Detect and use all 8 bits of CMAP color, if provided, when running
  157. under V39 or higher machine.  If you see the new BMHDF_CMAPOK flag
  158. set in BMHD.Flags (described above), then you can be sure that
  159. the CMAP already contains 8 significant bits per gun of color.
  160. If you are running under V39 or higher, scale each 8-bit gun value
  161. to 32-bits (by duplicating it in all 4 bytes of a ULONG), and load
  162. the colors using one of the V39 32-bit color loading functions
  163. (LoadRGB32, SetRGB32, SetRGB32CM).
  164.  
  165. If the BMHDF_CMAPOK bit is not set in the BMHD, then to display the
  166. CMAP colors correctly on an AA system, you need to determine if the
  167. stored CMAP color gun values are shifted 4-bit or full 8-bit values.
  168. If you do not examine the CMAP and instead just assume that it has 8
  169. significant bits, you will display the colors of many ILBMs incorrectly
  170. dim, while older LoadRGB4() loaders will actually display the correct
  171. colors (because the V39 4-bit color loading functions will scale the
  172. passed 4-bit values properly to 32-bits).
  173.  
  174. You can try to determine if the CMAP contains all 4-bit left-justified
  175. RGB values by examining the low nibble of every CMAP entry you intend to use
  176. (do not examine additional registers or garbage which may be stored
  177. in the CMAP).  
  178. If every examined low nibble is 0, then you would probably be correct to
  179. assume that the CMAP contains 4-bit left-justified values.  In this case,
  180. you can correctly scale these values to 32-bits by first scaling to
  181. 8 bits (i.e. duplicate the upper nibble of each gun into its low nibble),
  182. then scaling to 32-bits (as described above).  If any of the examined CMAP
  183. nibbles is non-zero, then the 8-bit CMAP values are directly scaled to 32-bits.
  184. Then load the colors using one of the V39 32-bit color loading functions.
  185.  
  186. When loading on a pre-V39 machine, just use the upper (most significant)
  187. nibble of each 8-bit CMAP gun value when calling the old 4-bit-per-gun
  188. pre-V39 graphics functions (LoadRGB4, SetRGB4, SetRGB4CM).
  189. Be very careful to AND out the the low nibble of each gun before shifting
  190. and OR'ing R, G, and B guns to create an xRGB word for pre-V39 functions.
  191.  
  192.  
  193. D.  Stop Limiting Color Register Load Counts to 32
  194.     ==============================================
  195.  
  196. Older IFF code, and even the early V37 NewIFF code would
  197. read any number of colors from an ILBM CMAP, but would
  198. only set a maximum 32 colors in the display.  
  199. Instead, the maximum number of colors set in the display
  200. should be limited by the display Viewport's ColorMap->Count
  201. rather than a hardcoded limit.  The current V37 and V39 NewIFF
  202. have no fixed limit on number of color registers.
  203.  
  204.  
  205. E.  Stop Limiting Depth to 5/6
  206.     ==========================
  207.  
  208. Older IFF code had fixed limits for the maximum allowable
  209. depth for displays and ILBMs.  Remove your limits.
  210. Display as much as the system can handle.  Don't reject
  211. depths and depth/mode combinations arbitrarily.
  212. Also, you may want to stop assuming that a 6-plane ILBM
  213. with no CAMG is HAM or HALFBRITE (although that might still
  214. be a good assumption since only a pretty lame program would
  215. write a HAM or HALFBRITE ILBM with no CAMG chunk).
  216.  
  217.  
  218. F. Watch out for BitMap->BytesPerRow
  219.    =================================
  220. We have seen a number of products which have problems with
  221. BitMap->BytesPerRow rounding changes under V39 with AA.
  222.  
  223. BitMap->BytesPerRow is a modulo - it is the number that must be added to the
  224. address of a bitmap byte to get to the same byte one scan line down.
  225. Prior to V39, the value of BitMap->BytesPerRow always happened to be
  226. the width of a bitmap scan line rounded up to the nearest multiple of 16,
  227. then divided by 8.  And all BitMaps, whether allocated via AllocRaster,
  228. or AllocMem using the RASSIZE macro, or via OpenScreen, had this
  229. same BytesPerRow rounding.  This rounding aligned every scanline on a
  230. word boundary to allow fetching by the word-oriented custom chips.  
  231.  
  232. In addition, the IFF ILBM spec states that the scan lines of an ILBM BODY
  233. must be saved as width rounded up to the nearest multiple of 16 pixels
  234. (i.e. as an even number of bytes width).
  235. So it is not surprising that assumptions about BitMap->ByesPerRow
  236. crept into ILBM handling code.
  237.  
  238. ILBM BODY scan lines must still be stored as pixel width rounded up
  239. to a multiple of 16.  But under V39 and AA, the higher bandwidth
  240. required to support new graphics modes requires that the scan lines
  241. of a displayable BitMap be aligned on larger boundaries.  Therefore
  242. under V39 and AA, the BytesPerRow of a BitMap must not be confused
  243. with the correct storage width of an ILBM.
  244.  
  245. In addition, graphic applications must be very careful not to assume
  246. that all BitMaps of the same width will have the same BytesPerRow.
  247. From V39 onwards, BitMaps allocated by different methods
  248. (e.g. OpenScreen, AllocRaster, AllocMem, AllocBitMap),
  249. or allocated for display by different chipsets (ECS, AA, etc.)
  250. or for different display modes or a promoted display mode, may have
  251. different scanline alignment restrictions and therefore a different
  252. BytesPerRow.  Do not assume that bitplanes allocated by different methods
  253. can be swapped, or processor copied across scanline boundaries.
  254.  
  255. To test for BitMap->BytesPerRow problems, you generally must test
  256. on an AA machine with either mode promotion or explicit use of higher
  257. bandwidth (greater alignment restriction) modes.
  258.  
  259. Common symptoms of BitMap->BytesPerRow problems are 1. a skewing of
  260. the display, where the pixels or each successive scan line all appear
  261. shifted to either the left or right, creating a diagonal effect, or
  262. 2. excess blank space at the right edge of an ILBM or a display.
  263.  
  264.  
  265. G. Watch out for interleaved bitmaps
  266.    =================================
  267.  
  268. If your application supports capturing any screen, you
  269. must watch out for the new interleaved bitmaps.
  270. An interleaved BitMap's BytesPerRow field is still the
  271. modulo for getting from any one pixel to the pixel directly
  272. below it, BUT it is no longer even related to the rounded up
  273. width of the screen or viewport.  Instead, it is a MUCH
  274. larger value which is actually the rounded up BitMap scan
  275. line width TIMES the depth.  Do not assume that BytesPerRow
  276. is related to the width of the display.
  277.  
  278. NOTE: The 2.0 Native Developer Update release of the NewIFF
  279. code had 2 major bugs.  The screen.c module had a 1.3
  280. incompatibility, and the ilbmr.c module could not properly
  281. save an interleaved bitmap (such as the V39 Workbench screen).
  282. See the newer version 37.10 of the NewIFF code.  This has
  283. been placed in our listings area on BIX, and sent to ADSP, and
  284. sent to Fred Fish.  For full AA color support, see the NewIFF39
  285. code (available to developers via BIX, ADSP, CIX and Devcon disks,
  286. and planned to be provided on the 3.0 Native Developer Update
  287. and given to Fred Fish).
  288.  
  289.  
  290. Under V39, an interleaved bitmap can be detected by:
  291.  
  292. if(GetBitMapAttr(bitmap_ptr,BMA_FLAGS) & BMF_INTERLEAVED)
  293. printf("is interleaved\n");
  294.  
  295.  
  296. H. Proper Printing of new Display Modes
  297.    ====================================
  298.  
  299. When dumping a rastport to printer under V36 and higher,
  300. the following IORequest field must contain a 32-bit modeid
  301. such as that returned by GetVPModeID(viewport).  You
  302. may want to allow the user the ability to print a display
  303. with a different modeid than it is being displayed in.
  304. Passing the full modeid allows the printer.device to
  305. properly control the aspect of the output, as long as the
  306. mode is available.
  307.  
  308.    ULONG   io_Modes;               /* graphics viewport modes */
  309.  
  310.  
  311.  
  312. -------------------------- getcamg -------------------------------
  313. From: /* ilbmr.c --- ILBM loading routines for use with iffparse */
  314.  
  315. /*
  316.  * Returns CAMG or computed mode for storage in ilbm->camg
  317.  *
  318.  * ilbm->Bmhd structure must be initialized prior to this call.
  319.  */
  320. ULONG getcamg(struct ILBMInfo *ilbm)
  321. {
  322. struct IFFHandle *iff;
  323. struct StoredProperty *sp;
  324. UWORD  wide,high,deep;
  325. ULONG modeid = 0L;
  326.  
  327.     if(!(iff=ilbm->ParseInfo.iff))return(0L);
  328.  
  329. wide = ilbm->Bmhd.pageWidth;
  330. high = ilbm->Bmhd.pageHeight;
  331. deep = ilbm->Bmhd.nPlanes;
  332.  
  333. D(bug("Getting CAMG for w=%ld h=%ld d=%ld ILBM\n",wide,high,deep));
  334.  
  335.         /*
  336.          * Grab CAMG's idea of the viewmodes.
  337.          */
  338.         if (sp = FindProp (iff, ID_ILBM, ID_CAMG))
  339.                 {
  340.                 modeid = (* (ULONG *) sp->sp_Data);
  341.  
  342.                 /* knock bad bits out of old-style 16-bit viewmode CAMGs
  343.                  */
  344.                 if((!(modeid & MONITOR_ID_MASK))||
  345.   ((modeid & EXTENDED_MODE)&&(!(modeid & 0xFFFF0000))))
  346.                    modeid &= 
  347.     (~(EXTENDED_MODE|SPRITES|GENLOCK_AUDIO|GENLOCK_VIDEO|VP_HIDE));
  348.  
  349.                 /* check for bogus CAMG like DPaintII brushes
  350.                  * with junk in upper word and extended bit
  351.                  * not set in lower word.
  352.                  */
  353.                 if((modeid & 0xFFFF0000)&&(!(modeid & 0x00001000))) sp=NULL;
  354.                 }
  355.  
  356.         if(!sp) {
  357.                 /*
  358.                  * No CAMG (or bad CAMG) present; use computed modes.
  359.                  */
  360.         modeid = 0L;
  361.                 if (wide >= 640)        modeid = HIRES;
  362.                 if (high >= 400)        modeid |= LACE;
  363.  
  364. /* This 6 planes == HAM or HALFBRITE is not
  365.  * necessarily true anymore, but hopefully
  366.  * all NEW programs are writing a proper CAMG chunk!!
  367.  */
  368.                 if (deep == 6)
  369.                         {
  370.                         modeid |= ilbm->EHB ? EXTRA_HALFBRITE : HAM;
  371.                         }
  372.  
  373. D(bug("No CAMG found - using mode $%08lx\n",modeid));
  374.                 }
  375.  
  376. D(bug("getcamg: modeid = $%08lx\n",modeid));
  377. return(modeid);
  378. }
  379.  
  380.  
  381. -------------------------- getaspect -------------------------------
  382.  
  383.     bmhd->xAspect = 0;  /* So we can tell when we've got it */
  384.     if(GfxBase->lib_Version >=36)
  385.         {
  386.         if(GetDisplayInfoData(NULL, (UBYTE *)&DI,
  387.                 sizeof(struct DisplayInfo), DTAG_DISP, modeid))
  388.                 {
  389.                 bmhd->xAspect =  DI.Resolution.x;
  390.                 bmhd->yAspect =  DI.Resolution.y;
  391.                 }
  392.         }
  393.  
  394.     /* If running under 1.3 or GetDisplayInfoData failed, use old method
  395.      * of guessing aspect ratio
  396.      */
  397.     if(! bmhd->xAspect)
  398.         {
  399.         bmhd->xAspect =  44;
  400.         bmhd->yAspect =
  401.                 ((struct GfxBase *)GfxBase)->DisplayFlags & PAL ? 44 : 52;
  402.         if(modeid & HIRES)      bmhd->xAspect = bmhd->xAspect >> 1;
  403.         if(modeid & LACE)       bmhd->yAspect = bmhd->yAspect >> 1;
  404.         }
  405.  
  406.