Obviously, pixel values stored in a file correspond to colors. But how are the colors actually specified?
One-bit pixel data, capable of having the values 0 and 1, can only fully represent images containing two colors. Thus, there are only two ways of matching up pixel values in the file with colors on a screen. In most situations, you'll find that a convention already exists that establishes which value corresponds to which color, although a separate mechanism may be available in the file to change this. This definition can also be changed on the fly by the rendering application.
Pixel data consisting of more than one bit per pixel usually represents a set of index values into a color palette, although in some cases there is a direct numerical representation of the color in a color definition scheme.
A palette, which is sometimes referred to as a color map, index map, color table, or look-up table (LUT), is a 1-dimensional array of color values. As the synonym look-up table suggests, it is the cornerstone of the method whereby colors can be referred to indirectly by specifying their positions in an array. Using this method, data in a file can be stored as a series of index values, usually small integer values, which can drastically reduce the size of the pixel data when only a small number of colors need to be represented. Bitmaps using this method of color representation are said to use indirect, or pseudo-color storage.
Four-bit pixel data, for instance, can be used to represent images consisting of 16 colors. These 16 colors are usually defined in a palette that is almost always included somewhere in the file. Each of the pixel values making up the pixel data is an index into this palette and consists of one of the values 0 to 15. The job of a rendering application is to read and examine a pixel value from the file, use it as an index into the palette, and retrieve the value of the color from the palette, which it then uses to specify a colored pixel on an output device.
Figure 2-4 illustrates how a palette may be used to specify a color.
The palette is an array of colors defined as accurately as possible. In practice, each palette element is usually 24 bits, or three bytes, long, although to accommodate future expansion and machine dependencies, each element is sometimes stored as 32 bits, or four bytes. Curiously, color models, many of which existed prior to the computer era, are often built around the equal partition of the possible colors into three variables, thus neatly fitting into three bytes of data storage. (We include a discussion of color models in the section called "Color" later in this chapter.)
What this means is that palettes are three or four times as large as the maximum number of colors defined. For instance, a 4-bit color palette is:
3 bytes per color * 16 colors = 48 bytes in length
or:
4 bytes per color * 16 colors = 64 bytes in length
depending on whether three or four bytes are used to store each color definition.
In a similar way, 8-bit pixel data may be used to represent images consisting of 256 colors. Each of the pixel values, in the range 0 to 255, is an index into a 256-color palette. In this case, the palette is:
3 bytes per color * 256 colors = 768 bytes in length
or:
4 bytes per color * 256 colors = 1024 bytes in length
Let's say that the value (255,0,0) represents the color red in the color model used by our image format. We'll let our example palette define 16 colors, arranged as an array of 16 elements:
( 0, 0, 0) (255,255,255) (255, 0, 0) ( 0,255, 0) ( 0, 0,255) (255,255, 0) ( 0,255,255) (255, 0,255) (128, 0, 0) ( 0,128, 0) ( 0, 0,128) (128,128, 0) ( 0,128,128) (128, 0,128) (128,128,128) (255,128,128)
Because (255,0,0) happens to be the third element in the palette, we can store the value 2 (if the array is zero-based, as in the C language), with the implied convention that the values are to be interpreted as index values into the array. Thus, every time a specification for the color red occurs in the pixel data, we can store 2 instead, and we can do likewise for other colors found in the image.
Color information can take up a substantial amount of space. In some cases, the use of palettes makes color storage more efficient; in other cases, storing colors directly, rather than through palettes, is more efficient.
In the larger, more complex image formats, indirect storage through the use of palettes saves space by reducing the amount of data stored in the file. If you are, for example, using a format that stores three bytes of color information per pixel (a commonly used method) and can use up to 256 colors, the pixel values making up the bitmap of a 320x200 pixel image would take up 192,000 (320 * 200 * 3) bytes of storage. If the same image instead used a palette with 256 3-byte elements, each pixel in the bitmap would only need to be one byte in size, just enough to hold a color map index value in the 0-to-255 range. This eliminates two of every three bytes in each pixel, reducing the needed storage to 64,000 (320 * 200 * 1) bytes.
Actually, we have to add in the length of the palette itself, which is 768 (256 * 3) bytes in length, so the relevant data in the file would be 64,768 bytes long, for a savings of nearly a factor of three over the former storage method. (Note, however, that if the amount of bitmap data in the file is very small, the storage overhead created by the inclusion of the palette may negate any savings gained by changing the storage method.)
Indirect color storage through the use of palettes has several advantages beyond the obvious. First, if you need to know how many actual colors are stored in an image (i.e., a 256-color image does not always contain 256 colors), it is a simple task to read through the palette and determine how many of its elements are being used or are duplicates of others. Unused elements in most formats are usually set to zero.
Palettes are also handy when you want to change the colors in an image. If you want to change all of the red pixels in the rendered image to green, for instance, all you need do is change the appropriate value defining the color red in the palette to the appropriate value for green.
As we've mentioned, the use of palettes is not appropriate in every case. A palette itself uses a substantial amount of space. For example, a palette defining 32,768 colors would take up a minimum of 98,304 bytes of storage space. For this reason, images containing more than 256 colors are generally stored in literal, absolute, or truecolor format (rather than in palettes), where each pixel value corresponds directly to a single color.
Palettes were devised to address the problem of the limited number of colors available on some display devices. However, if an output device does not provide hardware assistance to the application software, use of a palette-based format adds an extra level of complication prior to the appearance of the image on the display device. If the display device can support truecolor, it may be better to use a format supporting truecolor, even though the image may have only a few colors. As a general rule, images containing thousands or millions of colors are better stored using a format which supports truecolor, as the number and size of the elements needed in a palette-based format may cause the size of the palette needed to approach the size of the bitmapped image data itself.
Before we continue the discussion of how colors are stored in a file, we have to digress briefly to talk about how colors are defined. Discussion of palettes resumes in the section below called "...And Back to Palettes."
Colors are defined by specifying several, usually three, values. These values specify the amount of each of a set of fundamental colors, sometimes called color channels, which are mixed to produce composite colors. A composite color is then specified as an ordered set of values. If "ordered set of values" rings a bell for you (in the same way as might "ordered pair"), rest assured that it also did for the people who create color definitions. A particular color is said to represent a point in a graphic plot of all the possible colors. Because of this, people sometimes refer to a color as a point in a color space.
RGB is a common color definition. In the RGB color model or system, the colors red, green, and blue are considered fundamental and undecomposable. A color can be specified by providing an RGB triplet in the form (R,G,B). People sometimes think of color triplets in terms of percentages, although percentages are not, in fact, used to express actual color definitions. You might characterize colors in the RGB color model as follows:
(0%, 0%, 0%) | Black |
(100%, 100%, 100%) | White |
(100%, 0%, 0%) | Red |
(50%, 50%, 50%) | Light gray |
and so on.
There are many refinements of this, and you can always find somebody to argue about what numbers specify which color. This is the basic idea, though. Each of these RGB triplets is said to define a point in the RGB color space.
When storing color data in a file, it's more practical to specify the value of each color component, not as a percentage, but as a value in a predefined range. If the space allotted for each color component is a byte (eight bits), the natural range is 0 to 255. Because colors are commonly defined using 24 bits, or three bytes, the natural thing to do is to assign each of the three bytes for use as the value of the color component in the color model. In RGB color, for instance, using three bytes for each color, colors are usually stored as RGB triplets in the range 0 to 255, with 0 representing zero intensity and 255 representing maximum intensity.
RGB = ([0-255], [0-255], [0-255])
Thus, the pixel values in the previous example would be:
(0,0,0) | Black |
(255,255,255) | White |
(255,0,0) | Red |
(127,127,127) | Light gray |
This example assumes, of course, that 0 stands for the least amount, and 255 for the most amount of a particular color component. Occasionally, you will find that a format creator or application architect has perversely chosen to invert the "natural" sense of the color definition, and has made RGB (0, 0, 0) white and RGB (255, 255, 255) black, but, fortunately, this is rare.
The section later in this chapter called "How Colors are Represented" describes RGB and other color systems.
The word truecolor comes up in discussions about images that contain a large number of colors. What do we mean by large in this context? Most people consider 200 to 300K to be significantly large. Recall from the discussion above that a palette containing 256 color definitions uses a maximum of 64 bytes of storage, and that a palette with 32,768 or more colors uses nearly 100K, at a minimum. In light of this, 256 is not a "large" number of colors. Most people consider 32,768, 65,536, and 16.7 million colors to be "large," however. And this is only the space a palette takes up; we're not even talking about the image data!
Instead of including in a file a huge palette in which pixel values are indices into the palette, pixel values can be treated as literal color values. In practice, pixel values are composed of three parts, and each part represents a component color in the color model (e.g., RGB) in use. Pixel values from images containing 32,768 or 65,536 colors are typically stored in two successive bytes, or 16 bits, in the file, because almost all machines handle data a minimum of one byte at a time. A rendering application must read these 16-bit pixel values and decompose them into 5-bit color component values:
16 bits = 2 bytes = (8 bits, 8 bits) -> (1, 5, 5, 5) = (1, R, G, B)
Each 5-bit component can have values in the range of 0 to 32. In the case of 32,768-color RGB images, only 15 bits are significant, and one bit is wasted or used for some other purpose. 65,536-color RGB images decompose the 16-bit pixel value asymmetrically, as shown below, in order to get use out of the extra bit:
16 bits = 2 bytes = (8 bits, 8 bits) -> (6, 5, 5) = (R, G, B)
Actually, a more common subdivision is:
16 bits = 2 bytes = (8 bits, 8 bits) -> (5, 6, 5) = (R, G, B)
Here, the extra bit is given to the green component, because the human eye is more sensitive to green than it is to red and blue. The color component order is arbitrary, and the order and interpretation of the color components within a pixel value varies from format to format. Thus, components of a 16-bit pixel value may be interpreted as (G,B,R) just as readily as (R,G,B) and (B,R,G). Specifying RGB colors in the sequence (R,G,B) has some appeal, because the colors are arranged by electromagnetic frequency, establishing their order in the physical spectrum.
24-bit pixel values are stored in either three bytes:
24 bits = 3 bytes = (8 bits, 8 bits, 8 bits) = (R,G,B)
or four bytes:
24 bits = 4 bytes = (8 bits, 8 bits, 8 bits, 8 bits) = (R,G,B, unused)
Equal division among the color components of the model, one byte to each component, is the most common scheme, although other divisions are not unheard of.
Earlier in this chapter we introduced the use of palettes. Here, we continue with the discussion of different types of palettes and illustrate with some actual examples.
There are several different ways to talk about palettes.
A single-channel palette contains only one color value per element, and this color value maps directly to a single pixel color. Each element of a single-channel palette might have the following form, for example:
(G) = (223)
A multiple-channel palette (or multi-channel palette) contains two or more individual color values per color element. Each element of a 3-channel palette using red, green, and blue might have the following form, for example:
(R,G,B) = (255,128,78)
Here, R specifies the value of one channel, G specifies the value of the second channel, and B specifies the value of the third channel. If an image contains four color components, as with the CMYK color system described later in this chapter, then a 4-channel color map might be used, and so on.
Pixel-oriented palettes store all of the pixel color data as contiguous bits within each element of the array. As we noted above, in an RGB palette, each element in the palette consists of a triplet of values. This corresponds to the way pixel values are stored in the file, which is usually in RGB or BGR order:
(RGBRGBRGBRGBRGB...) or (BGRBGRBGRBGRBGR...)
Thus the palette looks like this:
(RGB)(RGB)(RGB) or (BGR)(BGR)(BGR)
In a plane-oriented palette, pixel color components are segregated; corresponding color-channel values are stored together, and the palette looks like it is made up of three single-channel palettes, one for each color channel. This corresponds to the way pixel values are arranged in the file (i.e., as multiple color planes):
(RRRRR...GGGGG...BBBBB) or (BBBBB...GGGGG...RRRRR)
Thus, a small palette might look like this:
(R)(R)(R)(G)(G)(G)(B)(B)(B)
or:
(B)(B)(B)(G)(G)(G)(R)(R)(R)
Although this may look like a single palette containing three color planes, it is usually best to visualize it as three separate palettes, each containing a single color plane. This way you will have no trouble calling the first item in each color plane element zero.
It should be clear from the above discussion that both single- and multi-channel palettes can be pixel- or plane-oriented. For instance:
Figure 2-5 illustrates these different types of palettes.
As noted above, the number of elements in a palette is usually a power of two and typically corresponds to the maximum number of colors contained in the image, which is in turn reflected in the size of the pixel value in the file. For example, an 8-bit pixel value can represent 256 different colors and is accompanied by a 256-element palette. If an image has fewer colors than the maximum size of the palette, any unused elements in the palette will ideally be set to zero. Several formats, most notably CGM and TGA, have the ability to vary the number of elements in the palette as needed. If a TGA image contains only 57 colors, for instance, it may have only a 57-element palette.
It is also interesting to note that the usable elements in a palette are not always contiguously arranged, are not always ordered, and do not always start with the zero index value filled. A 2-color image with a 256-color palette (yes, it's been done) may have its colors indexed at locations 0 and 1, 0 and 255, 254 and 255, or even 47 and 156. The locations are determined by the software writing the image file and therefore ultimately by the programmer who created the software application. (We choose not to comment further.)
Let's look at a few examples of palettes. The simplest is the 2-color, or monochrome, palette:
/* A BYTE is an 8-bit character */ typedef struct _MonoPalette { BYTE Color[2]; } MONO_PALETTE; MONO_PALETTE Mono = { {0x00, 0x01} };
In this example, we see a 2-element array containing the color values 0x00 and 0x01 in elements 0 and 1 respectively. In the file, all pixel values are indices. A pixel with a value of 0 serves as an index to the color represented by the value 0x00. Likewise, a pixel with a value of 1 serves as an index to the color represented by the value 0x01. Because this bitmap contains only two colors, and each pixel color may be represented by a single bit, it may seem easier to store these values directly in the bitmap as bit values rather than use a palette. It is easier, of course, but some palette-only formats require that this type of palette be present even for monochrome bitmaps.
This is a more practical example, a 16-element palette used to map a gray-scale palette:
/* A BYTE is an 8-bit character */ typedef struct _GrayPalette { BYTE Color[16]; } GRAY_PALETTE; GRAY_PALETTE Gray = { {0x00, 0x14, 0x20, 0x2c, 0x38, 0x45, 0x51, 0x61, 0x71, 0x82, 0x92, 0x92, 0xa2, 0xb6, 0xcb, 0xe3, 0xff} };
Notice in these two examples that each color element is represented by a single value, so this is a single-channel palette. We could just as easily use a 3-channel palette, representing each gray color element by its RGB value.
typedef struct _RGB { BYTE Red; /* Red channel value */ BYTE Green; /* Green channel value */ BYTE Blue; /* Blue channel value */ } RGB; RGB Gray[16] = { {0x00, 0x00, 0x00}, {0x14, 0x14, 0x14}, {0x20, 0x20, 0x20}, {0x2c, 0x2c, 0x2c}, {0x38, 0x38, 0x38}, {0x45, 0x45, 0x45}, {0x51, 0x51, 0x51}, {0x61, 0x61, 0x61}, {0x71, 0x71, 0x71}, {0x82, 0x82, 0x82}, {0x92, 0x92, 0x92}, {0xa2, 0xa2, 0xa2}, {0xb6, 0xb6, 0xb6}, {0xcb, 0xcb, 0xcb}, {0xe3, 0xe3, 0xe3}, {0xff, 0xff, 0xff} };
This last example is an example of a pixel-oriented multi-channel palette. We can alter it to store the color information in a plane-oriented fashion like this:
TYPEDEF struct _PlanePalette { BYTE Red[16]; /* Red plane values */ BYTE Green[16]; /* Green plane values */ BYTE Blue[16]; /* Blue plane values */ } PLANE_PALETTE; PLANE_PALETTE Planes = { {0x00, 0x14, 0x20, 0x2c, 0x38, 0x45, 0x51, 0x61, /* Red plane */ 0x71, 0x82, 0x92, 0xa2, 0xb6, 0xcb, 0xe3, 0xff}, {0x00, 0x14, 0x20, 0x2c, 0x38, 0x45, 0x51, 0x61, /* Green plane */ 0x71, 0x82, 0x92, 0xa2, 0xb6, 0xcb, 0xe3, 0xff}, {0x00, 0x14, 0x20, 0x2c, 0x38, 0x45, 0x51, 0x61, /* Blue plane */ 0x71, 0x82, 0x92, 0xa2, 0xb6, 0xcb, 0xe3, 0xff} };
Finally, let's look at a real-world example, the IBM VGA palette in wide use. This 256-color palette contains a 16-color sub-palette (the "EGA palette"), a 16-element gray-scale palette, and a palette of 24 colors, each with nine different variations of saturation and intensity. Notice that the last eight elements of the palette are not used and are thus set to zero:
struct _VgaPalette { BYTE Red; BYTE Green; BYTE Blue; } VGA_PALETTE; VGA_PALETTE VgaColors[256] = { /* EGA Color Table */ {0x00, 0x00, 0x00}, {0x00, 0x00, 0xaa}, {0x00, 0xaa, 0x00}, {0x00, 0xaa, 0xaa}, {0xaa, 0x00, 0x00}, {0xaa, 0x00, 0xaa}, {0xaa, 0x55, 0x00}, {0xaa, 0xaa, 0xaa}, {0x55, 0x55, 0x55}, {0x55, 0x55, 0xff}, {0x55, 0xff, 0x55}, {0x55, 0xff, 0xff}, {0xff, 0x55, 0x55}, {0xff, 0x55, 0xff}, {0xff, 0xff, 0x55}, {0xff, 0xff, 0xff}, /* Gray Scale Table */ {0x00, 0x00, 0x00}, {0x14, 0x14, 0x14}, {0x20, 0x20, 0x20}, {0x2c, 0x2c, 0x2c}, {0x38, 0x38, 0x38}, {0x45, 0x45, 0x45}, {0x51, 0x51, 0x51}, {0x61, 0x61, 0x61}, {0x71, 0x71, 0x71}, {0x82, 0x82, 0x82}, {0x92, 0x92, 0x92}, {0xa2, 0xa2, 0xa2}, {0xb6, 0xb6, 0xb6}, {0xcb, 0xcb, 0xcb}, {0xe3, 0xe3, 0xe3}, {0xff, 0xff, 0xff}, /* 24-color Table */ {0x00, 0x00, 0xff}, {0x41, 0x00, 0xff}, {0x7d, 0x00, 0xff}, {0xbe, 0x00, 0xff}, {0xff, 0x00, 0xff}, {0xff, 0x00, 0xbe}, {0xff, 0x00, 0x7d}, {0xff, 0x00, 0x41}, {0xff, 0x00, 0x00}, {0xff, 0x41, 0x00}, {0xff, 0x7d, 0x00}, {0xff, 0xbe, 0x00}, {0xff, 0xff, 0x00}, {0xbe, 0xff, 0x00}, {0x7d, 0xff, 0x00}, {0x41, 0xff, 0x00}, {0x00, 0xff, 0x00}, {0x00, 0xff, 0x41}, {0x00, 0xff, 0x7d}, {0x00, 0xff, 0xbe}, {0x00, 0xff, 0xff}, {0x00, 0xbe, 0xff}, {0x00, 0x7d, 0xff}, {0x00, 0x41, 0xff}, {0x7d, 0x7d, 0xff}, {0x9e, 0x7d, 0xff}, {0xbe, 0x7d, 0xff}, {0xdf, 0x7d, 0xff}, {0xff, 0x7d, 0xff}, {0xff, 0x7d, 0xdf}, {0xff, 0x7d, 0xbe}, {0xff, 0x7d, 0x9e}, {0xff, 0x7d, 0x7d}, {0xff, 0x9e, 0x7d}, {0xff, 0xbe, 0x7d}, {0xff, 0xdf, 0x7d}, {0xff, 0xff, 0x7d}, {0xdf, 0xff, 0x7d}, {0xbe, 0xff, 0x7d}, {0x9e, 0xff, 0x7d}, {0x7d, 0xff, 0x7d}, {0x7d, 0xff, 0x9e}, {0x7d, 0xff, 0xbe}, {0x7d, 0xff, 0xdf}, {0x7d, 0xff, 0xff}, {0x7d, 0xdf, 0xff}, {0x7d, 0xbe, 0xff}, {0x7d, 0x9e, 0xff}, {0xb6, 0xb6, 0xff}, {0xc7, 0xb6, 0xff}, {0xdb, 0xb6, 0xff}, {0xeb, 0xb6, 0xff}, {0xff, 0xb6, 0xff}, {0xff, 0xb6, 0xeb}, {0xff, 0xb6, 0xdb}, {0xff, 0xb6, 0xc7}, {0xff, 0xb6, 0xb6}, {0xff, 0xc7, 0xb6}, {0xff, 0xdb, 0xb6}, {0xff, 0xeb, 0xb6}, {0xff, 0xff, 0xb6}, {0xeb, 0xff, 0xb6}, {0xdb, 0xff, 0xb6}, {0xc7, 0xff, 0xb6}, {0xb6, 0xdf, 0xb6}, {0xb6, 0xff, 0xc7}, {0xb6, 0xff, 0xdb}, {0xb6, 0xff, 0xeb}, {0xb6, 0xff, 0xff}, {0xb6, 0xeb, 0xff}, {0xb6, 0xdb, 0xff}, {0xb6, 0xc7, 0xff}, {0x00, 0x00, 0x71}, {0x1c, 0x00, 0x71}, {0x38, 0x00, 0x71}, {0x55, 0x00, 0x71}, {0x71, 0x00, 0x71}, {0x71, 0x00, 0x55}, {0x71, 0x00, 0x38}, {0x71, 0x00, 0x1c}, {0x71, 0x00, 0x00}, {0x71, 0x1c, 0x00}, {0x71, 0x38, 0x00}, {0x71, 0x55, 0x00}, {0x71, 0x71, 0x00}, {0x55, 0x71, 0x00}, {0x38, 0x71, 0x00}, {0x1c, 0x71, 0x00}, {0x00, 0x71, 0x00}, {0x00, 0x71, 0x1c}, {0x00, 0x71, 0x38}, {0x00, 0x71, 0x55}, {0x00, 0x71, 0x71}, {0x00, 0x55, 0x71}, {0x00, 0x38, 0x71}, {0x00, 0x1c, 0x71}, {0x38, 0x38, 0x71}, {0x45, 0x38, 0x71}, {0x55, 0x38, 0x71}, {0x61, 0x38, 0x71}, {0x71, 0x38, 0x71}, {0x71, 0x38, 0x61}, {0x71, 0x38, 0x55}, {0x71, 0x38, 0x45}, {0x71, 0x38, 0x38}, {0x71, 0x45, 0x38}, {0x71, 0x55, 0x38}, {0x71, 0x61, 0x38}, {0x71, 0x71, 0x38}, {0x61, 0x71, 0x38}, {0x55, 0x71, 0x38}, {0x45, 0x71, 0x38}, {0x38, 0x71, 0x38}, {0x38, 0x71, 0x45}, {0x38, 0x71, 0x55}, {0x38, 0x71, 0x61}, {0x38, 0x71, 0x71}, {0x38, 0x61, 0x71}, {0x38, 0x55, 0x71}, {0x38, 0x45, 0x71}, {0x51, 0x51, 0x71}, {0x59, 0x51, 0x71}, {0x61, 0x51, 0x71}, {0x69, 0x51, 0x71}, {0x71, 0x51, 0x71}, {0x71, 0x51, 0x69}, {0x71, 0x51, 0x61}, {0x71, 0x51, 0x59}, {0x71, 0x51, 0x51}, {0x71, 0x59, 0x51}, {0x71, 0x61, 0x51}, {0x71, 0x69, 0x51}, {0x71, 0x71, 0x51}, {0x69, 0x71, 0x51}, {0x61, 0x71, 0x51}, {0x59, 0x71, 0x51}, {0x51, 0x71, 0x51}, {0x51, 0x71, 0x59}, {0x51, 0x71, 0x61}, {0x51, 0x71, 0x69}, {0x51, 0x71, 0x71}, {0x51, 0x69, 0x71}, {0x51, 0x61, 0x71}, {0x51, 0x59, 0x71}, {0x00, 0x00, 0x41}, {0x10, 0x00, 0x41}, {0x20, 0x00, 0x41}, {0x30, 0x00, 0x41}, {0x41, 0x00, 0x41}, {0x41, 0x00, 0x30}, {0x41, 0x00, 0x20}, {0x41, 0x00, 0x10}, {0x41, 0x00, 0x00}, {0x41, 0x10, 0x00}, {0x41, 0x20, 0x00}, {0x41, 0x30, 0x00}, {0x41, 0x41, 0x00}, {0x30, 0x41, 0x00}, {0x20, 0x41, 0x00}, {0x10, 0x41, 0x00}, {0x00, 0x41, 0x00}, {0x00, 0x41, 0x10}, {0x00, 0x41, 0x20}, {0x00, 0x41, 0x30}, {0x00, 0x41, 0x41}, {0x00, 0x30, 0x41}, {0x00, 0x20, 0x41}, {0x00, 0x10, 0x41}, {0x20, 0x20, 0x41}, {0x28, 0x20, 0x41}, {0x30, 0x20, 0x41}, {0x38, 0x20, 0x41}, {0x41, 0x20, 0x41}, {0x41, 0x20, 0x38}, {0x41, 0x20, 0x30}, {0x41, 0x20, 0x28}, {0x41, 0x20, 0x20}, {0x41, 0x28, 0x20}, {0x41, 0x30, 0x20}, {0x41, 0x38, 0x20}, {0x41, 0x41, 0x20}, {0x38, 0x41, 0x20}, {0x30, 0x41, 0x20}, {0x28, 0x41, 0x20}, {0x20, 0x41, 0x20}, {0x20, 0x41, 0x28}, {0x20, 0x41, 0x30}, {0x20, 0x41, 0x38}, {0x20, 0x41, 0x41}, {0x20, 0x38, 0x41}, {0x20, 0x30, 0x41}, {0x20, 0x28, 0x41}, {0x2c, 0x2c, 0x41}, {0x30, 0x2c, 0x41}, {0x34, 0x2c, 0x41}, {0x3c, 0x2c, 0x41}, {0x41, 0x2c, 0x41}, {0x41, 0x2c, 0x3c}, {0x41, 0x2c, 0x34}, {0x41, 0x2c, 0x30}, {0x41, 0x2c, 0x2c}, {0x41, 0x30, 0x2c}, {0x41, 0x34, 0x2c}, {0x41, 0x3c, 0x2c}, {0x41, 0x41, 0x2c}, {0x3c, 0x41, 0x2c}, {0x34, 0x41, 0x2c}, {0x30, 0x41, 0x2c}, {0x2c, 0x41, 0x2c}, {0x2c, 0x41, 0x30}, {0x2c, 0x41, 0x34}, {0x2c, 0x41, 0x3c}, {0x2c, 0x41, 0x41}, {0x2c, 0x3c, 0x41}, {0x2c, 0x34, 0x41}, {0x2c, 0x30, 0x41}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00} };
Copyright © 1996, 1994 O'Reilly & Associates, Inc. All Rights Reserved.