Cross-fading between 2 bitmaps using palette animation.
-------------------------------------------------------

The basic premise behind the Fade sample application is to 
take two 16-color (4 bpp) DIBs and create a single 256-color 
(8 bpp) DIB that contains color and pixel information for 
both images.  To do this, a 256-color palette is created from 
the two 16-color palettes, however, it is helpful to think 
of the 256-color palette as a 16x16, two dimensional array 
rather than a linear (one dimensional) palette:


   | 0      1      2      3      ...
 --+-------------------------------------
 0 | Black  Black  Black  Black  ...
 1 | Red    Red    Red    Red    ...
 2 | Green  Green  Green  Green  ...
 3 | Yellow Yellow Yellow Yellow ...
 etc.

For simplicity, assume both 4-bpp bitmaps have the same 
dimensions, so the resultant 8-bpp bitmap will have those 
same dimensions.  Each pixel has one color in the first bitmap 
and a second color in the second bitmap (possibly the same 
color).  Since the bit values for a pixel in a DIB are really 
just offsets into the color table for the DIB, say we have a 
pixel that uses color 2 (starting from zero) in the first bitmap 
and color 3 in the second bitmap.  That pixel will use color 
index 23 (hex) in the target (8-bpp) bitmap.  In other words, 
that pixel will use the color in row 2 and column 3 of the 
16x16 color array.  In this manner we can construct the bits 
for the target bitmap.

So how are the colors in the array determined?  And how does 
palette animation come into play?  Suppose we adjust the colors 
in the color array so that each row is a single color with the 
first row being the first color in the first color table (from the 
first 16-color bitmap), the second row being the second color, etc.  
This situation is shown in the above table.

If the 8-bpp DIB is now displayed using this color array as 
its palette, it will appear to be exactly the same as the first 
bitmap.  Similarly, if we change the array so that each column 
contains the corresponding color from the second color table, 
the 8-bpp DIB will appear to be the second bitmap.  This is where 
palette animation comes into play.  By simply calling 
AnimatePalette(), we can change between the two images without 
creating a new bitmap or performing any kind of BitBlt().  Fast!

Furthermore, by using intermediate steps in the palette animation, 
the image on the screen can be made to look like a combination 
of the two images.  Say that we set up the color array such that 
the color in position (n,m) has 30% of color n from the first 
color table and 70% of color m from the second color table, and 
we animate the palette to have these colors.  What appears on the 
screen is a combination of the two images showing less of the first 
bitmap (30%) and more of the second bitmap (70%).  The images are 
blended together one on top of the other.  By starting from one 
set of colors and stepping through to the other colors, mixing and 
resetting the colors with AnimatePalette() for each step, the 
bitmap will appear to fade smoothly from one image to the other.

Doing this in Windows requires some special considerations.  First, 
it requires a 256-color palettized display to work.  Even though we 
are only working with 16-color bitmaps, standard VGA won't do.

Second, working with the 8-bpp 'dual bitmap' requires using 
DIB_PAL_COLORS rather than DIB_RGB_COLORS.  To get this technique 
to work, the pixels in the 8-bpp DIB must refer to specific 
palette entries rather than specific colors.  The main problem with
using DIB_RGB_COLORS is that multiple occurrances of a single color
will be mapped to the same system palette entry, which doesn't suit
our purposes here.

Third, to animate between two 16-color bitmaps requires a 256 (=16*16) 
color palette.  In Windows, this means using SetSystemPaletteUse() to 
take over the reserved system colors (except for black and white) and 
making do with the 254 system palette entries available for animation.  
One big drawback is that this makes for rather ugly windows, especially 
since some of the system colors, such as the button face color, cannot 
be changed to black or white, which are the only two colors that won't 
be changing.  (That is, there are always some  colors on the desktop 
that will change as the palette is animated.)  A second problem is the 
loss of two palette entries for animation.  The Fade sample takes this 
into account by arranging the colors so that pixels that would animate 
between the two darkest colors in the 2 bitmaps simply map to black 
(and never animate) and pixels that would animate between the two 
lightest colors map to white.  Since black and white are frequently 
in the color tables of the two 16-color bitmaps, this loss is often 
unnoticeable.  The pixels involved would simply be animating from black 
to black or from white to white anyway.

Another way around these problems is to use fewer colors, say 15, in 
each of the component bitmaps.  By doing this, only 225 (=15*15) palette 
entries are required for animation.  This modification allows for 
maintaining the 20 Windows system colors and still leaves enough space 
in the palette for the entire 225 colors.  The problem with this method, 
at least when starting with existing 16-color bitmaps, is which color 
to eliminate.  Fade does this by letting the user experiment and choose 
one color which is changed to another color.  The conversion is done by 
manipulating the DIB_PAL_COLORS indices in the color table; the pixel 
values are not modified.

Actually, the theory behind all of this does not require that the color 
matrix be square.  There is no reason why one of the bitmaps couldn't 
have 50 colors and the other one have 4 colors.  In this case, the 
matrix would have the dimensions 50 x 4 for a total of 200 palette 
entries.  This is one way that Fade could be enhanced.

