Also Known As: Graphics Interchange Format
Type | Bitmap |
Colors | 1 to 8 bit |
Compression | LZW |
Maximum Image Size | 64Kx64K pixels |
Multiple Images Per File | Yes |
Numerical Format | Little-endian |
Originator | CompuServe, Inc. |
Platform | MS-DOS, Macintosh, UNIX, Amiga, others |
Supporting Applications | Too numerous to list |
See Also | Chapter 9, Data Compression |
Usage
Originally designed to facilitate image transfer and online
storage for use by CompuServe and its customers,
GIF is primarily an exchange and storage
format, although it is based on, and is supported by, many
applications.
Comments
A well-defined, well-documented format in wide use, which is
quick, easy to read, and reasonably easy to uncompress. It lacks,
however, support for the storage of deep-pixel images.
Vendor specifications are available for this format.
Code fragments are available for this format.
Sample images are available for this format.
GIF (Graphics Interchange Format) is a creation of CompuServe and is used to store multiple bitmap images in a single file for exchange between platforms and systems. In terms of number of files in existence, GIF is perhaps the most widely used format for storing multibit graphics and image data. Even a quick peek into the graphics file section of most BBSs and file archives seems to prove this true. Many of these are high-quality images of people, landscapes, cars, astrophotographs, and anthropometric gynoidal data (you guess what that is). Shareware libraries and BBSs are filled with megabytes of GIF images.
Contents:
File Organization
File Details
For Further Information
The vast majority of GIF files contain 16-color or 256-color near-photographic quality images. Gray-scale images, such as those produced by scanners, are also commonly stored using GIF, although monochrome graphics, such as clip art and document images, rarely are.
Although the bulk of GIF files are found in the Intel-based MS-DOS environment, GIF is not associated with any particular software application. GIF also was not created for any particular software application need, although most software applications that read and write graphical image data, such as paint programs, scanner and video software, and most image file display and conversion programs, usually support GIF. GIF was instead intended to allow the easy interchange and viewing of image data stored on local or remote computer systems.
GIF is different from many other common bitmap formats in the sense that it is stream-based. It consists of a series of data packets, called blocks, along with additional protocol information. Because of this arrangement, GIF files must be read as if they are a continuous stream of data. The various blocks and sub-blocks of data defined by GIF may be found almost anywhere within the file. This uncertainty makes it difficult to encapsulate every possible arrangement of GIF data in the form of C structures.
There are a number of different data block categories, and each of the various defined blocks falls into one of these categories. In GIF terminology, a Graphics Control Extension block is a type of Graphics Control block, for instance. In like manner, Plain Text Extension blocks and the Local Image Descriptor are types of Graphic Rendering blocks. The bitmap data is an Image Data block. Comment Extension and Application Extension blocks are types of Special Purpose blocks.
Blocks, in addition to storing fields of information, can also contain sub-blocks. Each data sub-block begins with a single count byte, which can be in the range of 1 to 255 and indicates the number of data bytes that follow the count byte. Multiple sub-blocks may occur in a contiguous grouping (count byte, data bytes, count byte, data bytes, and so on). A sequence of one or more data sub-blocks is terminated by a count byte with a value of zero.
The GIF format is capable of storing bitmap data with pixel depths of 1 to 8 bits. Images are always stored using the RGB color model and palette data. GIF is also capable of storing multiple images per file, but this capability is rarely utilized, and the vast majority of GIF files contain only a single image. Most GIF file viewers do not, in fact, support the display of multiple image GIF files or may display only the first image stored in the file. For these reasons, we recommend not creating applications that rely on multiple images per file, even though the specification allows this.
The image data stored in a GIF file is always LZW compressed. See Chapter 9 for a discussion of LZW and other compression methods (and also see the sidebar below). This algorithm reduces strings of identical byte values into a single code word and is capable of reducing the size of typical 8-bit pixel data by 40 percent or more. The ability to store uncompressed data, or data encoded using a different compression algorithm, is not supported in the current version of the GIF format.
LZW Is Not Free If you are creating or modifying software that implements the LZW algorithm, be aware that under certain circumstances, you will need to pay a licensing fee for the use of LZW.
Unisys Corporation owns the patent for the LZW codec (encoding/decoding algorithm) and requires that a licensing fee be paid for each software program that implements the LZW algorithm.
Many people have concluded that the Unisys licensing claim applies only to LZW encoders (software that creates LZW data) and not to LZW decoders (software that only reads LZW data). However, Unisys believes that its patent covers the full LZW codec and requires a licensing fee even for software that reads, but does not write, LZW data.
For more information about the entire issue of LZW licensing, refer to the section called "LZW Legal Issues" in Chapter 9. For a popular alternative to graphics file formats that use LZW, consider using the Portable Network Graphics (PNG) file format.
There are two revisions of the GIF specification, both of which have been widely distributed. The original revision was GIF87a, and many images were created in this format. The current revision, GIF89a, adds several capabilities, including the ability to store text and graphics data in the same file. If you are supporting GIF, you should include support for both the 87a and 89a revisions. It is a mistake to support only the 89a version, because many applications continue to produce only 87a version files for backward compatibility.
The "GIF87a" section here discusses features common to both versions; the "GIF89a" section describes only the features added in GIF89a.
Version 87a is the original GIF format introduced in May 1987 and is read by all major software applications supporting the GIF format.
Figure GIF-1 illustrates the basic layout of a GIF87a file. Each file always begins with a Header and a Logical Screen Descriptor. A Global Color Table may optionally appear after the Logical Screen Descriptor. Each of these three sections is always found at the same offset from the start of the file. Each image stored in the file contains a Local Image Descriptor, an optional Local Color Table, and a block of image data. The last field in every GIF file is a Terminator character, which indicates the end of the GIF data stream.
The Header is six bytes in size and is used only to identify the file as type GIF. The Logical Screen Descriptor, which may be separate from the actual file header, may be thought of as a second header. We may therefore store the Logical Screen Descriptor information in the same structure as the Header:
typedef struct _GifHeader { // Header BYTE Signature[3]; /* Header Signature (always "GIF") */ BYTE Version[3]; /* GIF format version("87a" or "89a") */ // Logical Screen Descriptor WORD ScreenWidth; /* Width of Display Screen in Pixels */ WORD ScreenHeight; /* Height of Display Screen in Pixels */ BYTE Packed; /* Screen and Color Map Information */ BYTE BackgroundColor; /* Background Color Index */ BYTE AspectRatio; /* Pixel Aspect Ratio */ } GIFHEAD;
Signature is three bytes in length and contains the characters GIF as an identifier. All GIF files start with these three bytes, and any file that does not should not be read by an application as a GIF image file.
Version is also three bytes in length and contains the version of the GIF file. There are currently only two versions of GIF: 87a (the original GIF format) and 89a (the new GIF format). Some GIF87a file viewers may be able to read GIF89a files, although the stored image data may not display correctly.
The Logical Screen Descriptor contains information describing the screen and color information used to create and display the GIF file image.
The ScreenHeight and ScreenWidth fields contain the minimum screen resolution required to display the image data. If the display device is not capable of supporting the specified resolution, some sort of scaling will be necessary to properly display the image.
Packed contains the following four subfields of data (bit 0 is the least significant bit, or LSB):
Bits 0-2 | Size of the Global Color Table |
Bit 3 | Color Table Sort Flag |
Bits 4-6 | Color Resolution |
Bit 7 | Global Color Table Flag |
The Size of the Global Color Table subfield contains the number of bits in each Global Color Table entry minus one. For example, if an image contains 8 bits per pixel, the value of this field is 7. The total number of elements in the Global Color Table is calculated by shifting the value one to the left by the value in this field:
NumberOfGlobalColorTableEntries = (1L << (SizeOfTheGlobalColorTable + 1));
The Size of the Global Color Table subfield is always set to the proper size even if there is no Global Color Table (i.e., the Global Color Table Flag subfield is set to 0). If the Color Table Sort Flag subfield is 1, then the Global Color Table entries are sorted from the most important (most frequently occurring color in the image) to the least important. Sorting the colors in the color table aids an application in choosing the colors to use with display hardware that has fewer available colors than the image data. The Sort flag is only valid under version 89a of GIF. Under version 87a, this field is reserved and is always set to 0.
The Color Resolution subfield is set to the number of bits in an entry of the original color palette minus one. This value equates to the maximum size of the original color palette. For example, if an image originally contained eight bits per primary color, the value of this field would be 7. The Global Color Table Flag subfield is set to 1 if a Global Color Table is present in the GIF file, and 0 if one is not. Global Color Table data, if present, always follows the Logical Screen Descriptor header in the GIF file.
BackgroundColor in the Logical Screen Descriptor contains an index value into the Global Color Table of the color to use for the border and background of the image. The background is considered to be the area of the screen not covered by the GIF image. If there is no Global Color Table (i.e., the Global Color Table Flag subfield is set to 0), this field is unused and should be ignored.
AspectRatio contains the aspect ratio value of the pixels in the image. The aspect ratio is the width of the pixel divided by the height of the pixel. This value is in the range of 1 to 255 and is used in the following calculation:
PixelAspectRatio = (AspectRatio + 15) / 64;
If this field is 0, then no aspect ratio is specified.
The Logical Screen Descriptor may be followed by an optional Global Color Table. This color table, if present, is the color map used to index the pixel color data contained within the image data. If a Global Color Table is not present, each image stored in the GIF file contains a Local Color Table that it uses in place of a Global Color Table. If every image in the GIF file uses its own Local Color Table, then a Global Color Table may not be present in the GIF file. If neither a Global nor a Local Color Table is present, make sure your application supplies a default color table to use. It is suggested that the first entry of a default color table be the color black and the second entry be the color white.
Global Color Table data always follows the Logical Screen Descriptor information and varies in size depending upon the number of entries in the table. The Global Color Table is a series of three-byte triples making up the elements of the color table. Each triple contains the red, green, and blue primary color values of each color table element:
typedef struct _GifColorTable { BYTE Red; /* Red Color Element */ BYTE Green; /* Green Color Element */ BYTE Blue; /* Blue Color Element */ } GIFCOLORTABLE;
The number of entries in the Global Color Table is always a power of two (2, 4, 8, 16, and so on), up to a maximum of 256 entries. The size of the Global Color Table in bytes is calculated by using bits 0, 1, and 2 in the Packed field of the Logical Image Descriptor in the following way:
ColorTableSize = 3L * (1L << (SizeOfGlobalColorTable + 1));
The Header, Logical Screen Descriptor, and Global Color Map data are followed by one or more sections of image data. Each image in a GIF file is stored separately, with an Image Descriptor and possibly a Local Color Table. The Image Descriptor is similar to a header and contains information only about the image data that immediately follows it. The Local Color Table contains color information specific only to that image data and may or may not be present.
The Local Image Descriptor appears before each section of image data and has the following structure:
typedef struct _GifImageDescriptor { BYTE Separator; /* Image Descriptor identifier */ WORD Left; /* X position of image on the display */ WORD Top; /* Y position of image on the display */ WORD Width; /* Width of the image in pixels */ WORD Height; /* Height of the image in pixels */ BYTE Packed; /* Image and Color Table Data Information */ } GIFIMGDESC;
Separator contains the value 2Ch and denotes the beginning of the Image Descriptor data block.
Left and Top are the coordinates in pixels of the upper-left corner of the image on the logical screen. The upper-left corner of the screen is considered to be coordinates 0,0.
Width and Height are the size of the image in pixels.
Packed contains the following five subfields of data (bit 0 is the LSB):
Bit 0 | Local Color Table Flag |
Bit 1 | Interlace Flag |
Bit 2 | Sort Flag |
Bits 3-4 | Reserved |
Bits 5-7 | Size of Local Color Table Entry |
The Local Color Table Flag subfield is 1 if a Local Color Table is associated with this image. If the value of this subfield is 0, then there is no Local Color Table present, and the Global Color Table data should be used instead.
The Interlace Flag subfield is 1 if the image is interlaced and 0 if it is non-interlaced. (See the description of Image Data for an explanation of interlaced image data.)
The Sort Flag subfield indicates whether the entries in the color table have been sorted by their order of importance. Importance is usually decided by the frequency of occurrence of the color in the image data. A value of 1 indicates a sorted color table, while a value of 0 indicates a table with unsorted color values. The Sort Flag subfield value is valid only under version 89a of GIF. Under version 87a, this field is reserved and is always set to 0.
The Size of Local Color Table Entry subfield is the number of bits per entry in the Local Color Table. If the Local Color Table Flag subfield is set to 0, then this subfield is also set to 0.
If a Local Color Table is present, it immediately follows the Local Image Descriptor and precedes the image data with which it is associated. The format of all Local Color Tables is identical to that of the Global Color Table. Each element is a series of 3-byte triples containing the red, green, and blue primary color values of each element in the Local Color Table:
typedef struct _GifColorTable { BYTE Red; /* Red Color Element */ BYTE Green; /* Green Color Element */ BYTE Blue; /* Blue Color Element */ } GIFCOLORTABLE;
The number of entries and the size in bytes of the Local Color Table is calculated in the same way as the Global Color Table:
ColorTableSize = 3L * (1L << (SizeOfLocalColorTable + 1)); ColorTableNumberOfEntries = 1L << (SizeOfLocalColorTable + 1);
A Local Color Table only affects the image it is associated with and, if it is present, its data supersedes that of the Global Color Table. Each image may have no more than one Local Color Table.
GIF files do not compress well when stored using file archivers such as pkzip and zoo. This is because the image data found in every GIF file is always compressed using the LZW (Lempel-Ziv-Welch) encoding scheme, the same compression algorithm used by most file archivers. (See the sidebar about LZW at the beginning of this article.) Compressing a GIF file is therefore a redundant operation, which rarely results in smaller files and is usually not worth the time and effort involved in the attempt.
Normally when LZW-encoded image data is stored in a graphics file format, it is arranged as a continuous stream of data that is read from beginning to end. The GIF format, however, stores encoded image data as a series of data sub-blocks.
Each data sub-block begins with a count byte. The value of the count byte may range from 1 to 255 and indicates the number of data bytes in the sub-block. The data blocks immediately follow the count byte. A contiguous group of data blocks is terminated by a byte with a zero value. This may be viewed as either a terminator value or as a sub-block with a count byte value of zero; in either case, it indicates that no data bytes follow.
Because GIF files do not contain a contiguous stream of LZW-encoded data, each sub-block must be read and the data sent to an LZW decoder. Most sub-blocks storing image data will be 255 bytes in length, so this is an excellent maximum size to use for the buffer that will hold the encoded image data. Also, the LZW encoding process does not keep track of where each scan line begins and ends. It is therefore likely that one scan line will end and another begin in the middle of a sub-block of image data.
The format of the decoded GIF image data is fairly straightforward. Each pixel in a decoded scan line is always one byte in size and contains an index value into either a Global or Local Color Table. Although the structure of the GIF format is quite capable of storing color information directly in the image data (thus bypassing the need for a color table), the GIF specification does not specify this as a possible option. Therefore, even 1-bit image data must use 8-bit index values and a 2-entry color table.
GIF image data is always stored by scan line and by pixel. GIF does not have the capability to store image data as planes, so when GIF files are displayed using plane-oriented display adapters, quite a bit of buffering, shifting, and masking of image data must first occur before the GIF image can be displayed.
The scan lines making up the GIF bitmap image data are normally stored in consecutive order, starting with the first row and ending with the last. The GIF format also supports an alternate way to store rows of bitmap data in an interlaced order. Interlaced images are stored as alternating rows of bitmap data. If you have ever viewed a GIF file that appeared on the screen as a series of four "wipes" that jumped across the screen as the image was displayed, you were viewing an interlaced GIF file.
Figure GIF-2 compares the order of rows stored in an interlaced and non-interlaced format. In the non-interlaced format, the rows of bitmap data are stored starting with the first row and continuing sequentially to the last row. This is the typical storage format for most bitmap file formats. The interlaced format, however, stores the rows out of the normal sequence. All the even rows are stored first and all the odd rows are stored last. We can also see that each successive pass usually encodes more rows than the previous pass.
GIF uses a four-pass interlacing scheme. The first pass starts on row 0 and reads every eighth row of bitmap data. The second pass starts on the fourth row and reads every eighth row of data. The third pass starts on the second row and reads every fourth row. The final pass begins on the first row and reads every second row. Using this scheme, all of the rows of bitmap data are read and stored.
Why interlace a GIF image? Interlacing might seem to make the reading, writing, and displaying of the image data more difficult, and of course it does. Does this arrangement somehow make the image easier to display on interlaced monitors? The answer lies in one of the original purposes of GIF.
GIF was designed as an image communications protocol used for the interactive viewing of online images. A user connected to an information service via a modem could not only download a GIF image, but could also see it appear on his or her display screen as it was being downloaded. If a GIF image were stored in a non-interlaced format, the GIF image would display in a progressive fashion starting at the top of the screen and ending at the bottom. After 50 percent of the download was completed, only the top half of the GIF image would be visible. An interlaced image, however, would display starting with every eighth row, then every fourth row, then every second row, and so on. When the download of an interlaced GIF image was only 50 percent complete, the entire contents of the image could be discerned even though only half the image had been displayed. The viewer's eye and brain would simply fill in the missing half.
Interlacing presents a problem when converting a GIF image from one format to another. A scan-line table must be created to write out the scan lines in their proper, non-interlaced order. The following sample code is used to produce a scan-line table of an interlaced image:
WORD i, j; WORD RowTable1[16]; WORD RowTable2[16]; WORD ImageHeight = 16; /* 16 lines in the GIF image */ for (i = 0; i < ImageHeight; i++) /* Initialize source array*/ RowTable1[i] = i; j = 0; for (i = 0; i < ImageHeight; i += 8, j++) /* Interlace Pass 1 */ RowTable2[i] = RowTable1[j]; for (i = 4; i < ImageHeight; i += 8, j++) /* Interlace Pass 2 */ RowTable2[i] = RowTable1[j]; for (i = 2; i < ImageHeight; i += 4, j++) /* Interlace Pass 3 */ RowTable2[i] = RowTable1[j]; for (i = 1; i < ImageHeight; i += 2, j++) /* Interlace Pass 4 */ RowTable2[i] = RowTable1[j];
The array RowTable1[] contains the mapping of the scan lines in a non-interlaced image, which in this example are the values 0 to 15 in consecutive order. The array RowTable2[] is then initialized by the interlacing code to contain the mapping of the scan lines of the interlaced image:
RowTable1[] RowTable2[] 0 0 1 8 2 4 3 9 4 2 5 10 6 5 7 11 8 1 9 12 10 6 11 13 12 3 13 14 14 7 15 15
We can restore the non-interlaced image by stepping through the values stored in RowTable2[]. The 0th row of the non-interlaced image is the 0th row of the interlaced image. The first row of the non-interlaced image is the eighth row of the interlaced image. The second row of the non-interlaced image is the fourth row of the interlaced image, and so on.
The Trailer is a single byte of data that occurs as the last character in the file. This byte value is always 3Bh and indicates the end of the GIF data stream. A trailer must appear in every GIF file.
Version 89a is the most recent revision of the GIF image file format and was introduced in July of 1989. Although the GIF89a format is very similar to GIF 87a, it contains several additional blocks of information not defined in the 87a specification. For this reason GIF89a image files may not be read and displayed properly by applications that read only GIF87a image files. Many of these programs do not not attempt to display an 89a image file, because the version number "89a" will not be recognized. Although changing the version number from "89a" to "87a" will solve this problem, the GIF image data may still not display properly, for reasons we shall soon see.
Figure GIF-3 illustrates the basic layout of a GIF89a image file. Just as with version 87a, the 89a version also begins with a Header, a Logical Screen Descriptor, and an optional Global Color Table. Each image also contains a Local Image Descriptor, an optional Local Color Table, and a block of image data. The trailer in every GIF89a file contains the same values found in 87a files.
Version 89a added a new feature to the GIF format called Control Extensions. These extensions to the GIF87a format are specialized blocks of information used to control the rendering of the graphical data stored within a GIF image file. The design of GIF87a only allowed the display of images one at a time in a "slide show" fashion. Through the interpretation and use of Control Extension data, GIF89a allows both textual and bitmap-based graphical data to be displayed, overlaid, and deleted as in an animated multimedia presentation.
The four Control Extensions introduced by GIF89a are the Graphics Control Extension, the Plain Text Extension, the Comment Extension, and the Application Extension, summarized here and described in greater detail in the sections below.
Graphics Control Extension blocks control how the bitmap or plain-text data found in a Graphics Rendering block is displayed. Such control information includes whether the graphic is to be overlaid in a transparent or opaque fashion over another graphic, whether the graphic is to be restored or deleted, and whether user input is expected before continuing with the display of the GIF file data.
Plain Text Extension blocks allow the mixing of plain-text ASCII graphics with bitmapped image data. Many GIF images contain human-readable text that is actually part of the bitmap data itself. Using the Plain Text Extension, captions that are not actually part of the bitmapped image may be overlaid onto the image. This can be invaluable when it is necessary to display textual data over an image, but it is inconvenient to alter the bitmap to include this information. It is even possible to construct an 89a file that contains only plain-text data and no bitmap image data at all.
Comment Extension blocks contain human-readable ASCII text embedded in the GIF data stream that is used in a manner similar to program comments in C language code.
Application Extension blocks allow the storage of data that is understood only by the software application reading the GIF file. This data could be additional information used to help display the image data or to coordinate the way the image data is displayed with other GIF image files.
With only a few restrictions, any number of Control Extension blocks may appear almost anywhere in a GIF data stream following the Global Color Table. All Extension blocks begin with the Extension Introducer value 21h, which identifies the block of data as an Extension block. This value is followed by a Block Label, which identifies the type of extension information contained within the block. Block Label identification values range from 00h to FFh. The Plain Text, Application, and Comment Extension blocks may also contain one or more sub-blocks of data.
Interestingly enough, all of the Control Extension features added by 89a are optional and are not required to appear in a GIF data stream. The only other difference between 87a and 89a is that at least one of the Image Descriptor and Logical Screen Descriptor fields, which are reserved under 87a, is used under 89a. In fact, any GIF files that are written under version 89a, but do not use any of the 89a features, should use the version number GIF87a.
The information found in a Graphics Control block is used to modify the data in the Graphical Rendering block that immediately follows it. A Graphics Control block may modify either bitmap or plain-text data. It must also occur in the GIF stream before the data it modifies, and only one Graphics Control block may appear per Graphics Rendering block.
The Graphics Control Extension block is eight bytes in length and has the following structure:
typedef struct _GifGraphicsControlExtension { BYTE Introducer; /* Extension Introducer (always 21h) */ BYTE Label; /* Graphic Control Label (always F9h) */ BYTE BlockSize; /* Size of remaining fields (always 04h) */ BYTE Packed; /* Method of graphics disposal to use */ WORD DelayTime; /* Hundredths of seconds to wait */ BYTE ColorIndex; /* Transparent Color Index */ BYTE Terminator; /* Block Terminator (always 0) */ } GIFGRAPHICCONTROL;
Introducer contains the value 21h and is used to identify the start of a Extension data block.
Label contains the value F9h and is used to identify this block of data as a Graphics Control Extension.
BlockSize contains the value 04h, which is the number of bytes in the Packed, DelayTime, and ColorIndex fields.
Packed contains the following four subfields of information (bit 0 is the LSB):
Bit 0 | Transparent Color Flag |
Bit 1 | User Input Flag |
Bits 2-4 | Disposal Method |
Bits 5-7 | Reserved |
If the Transparent Color Flag subfield is set to 1, the ColorIndex field of this extension contains a color transparency index. If no index is present, this bit is set to 0.
The User Input Flag subfield is set to 1 if user input (key press, mouse click, and so forth) is expected before continuing to the next graphic sequence; otherwise, this bit is set to zero.
The Disposal Method subfield contains a value indicating how the graphic is to be disposed of once it has been displayed. The currently defined values for this field are 00h (disposal method not specified), 01h (do not dispose of graphic), 02h (overwrite graphic with background color), and 04h (overwrite graphic with previous graphic).
The Reserved subfield is not used in GIF89a and is always set to 0.
DelayTime in the Graphics Control Extension block contains a value equal to the number of hundredths of a second that must elapse before the graphics presentation continues. If this field is 0, then no delay is used. If both this delay and the user input bit is set, the graphic continues when either the delay expires or user input is received.
ColorIndex is the color transparency index. This field contains a value only if the Transparent Color Flag subfield in the Packed field is set to 1.
Terminator contains the value 0 and marks the end of the Graphics Control Extension block.
GIF87a files may contain bitmapped data only in the form of a Graphical Rendering block. GIF89a adds the ability to store textual information that may be rendered as a graphical image.
Any number of Plain Text Extension blocks may appear in a GIF file. To display plain-text data, a grid is described that contains the data. The height, width, and position of the grid on the display screen are specified. The size of each cell in the grid is also described, and one character is displayed per cell. The foreground and background color of the text are taken from the Global Color Table and are also described in the Plain Text Extension block. The actual Plain Text data is a simple string of ASCII characters.
The Plain Text Extension block is 15 bytes in length and has the following structure:
typedef struct _GifPlainTextExtension { BYTE Introducer; /* Extension Introducer (always 21h) */ BYTE Label; /* Extension Label (always 01h) */ BYTE BlockSize; /* Size of Extension Block (always 0Ch) */ WORD TextGridLeft; /* X position of text grid in pixels */ WORD TextGridTop; /* Y position of text grid in pixels */ WORD TextGridWidth; /* Width of the text grid in pixels */ WORD TextGridHeight; /* Height of the text grid in pixels */ BYTE CellWidth; /* Width of a grid cell in pixels */ BYTE CellHeight; /* Height of a grid cell in pixels */ BYTE TextFgColorIndex; /* Text foreground color index value */ BYTE TextBgColorIndex; /* Text background color index value */ BYTE *PlainTextData; /* The Plain Text data */ BYTE Terminator; /* Block Terminator (always 0) */ } GIFPLAINTEXT;
Introducer contains the value 21h and is used to identify the start of a Extension data block.
Label contains the value 01h and is used to identify this block of data as a Plain Text Extension.
BlockSize contains the value 0Ch, which is the number of bytes contained in the fields following the BlockSize field.
TextGridLeft and TextGridTop contain the X and Y coordinates (position) of the text grid with respect to the upper-left corner of the display screen (coordinate 0,0).
TextGridWidth and TextGridHeight contain the size of the text grid in pixels.
CellWidth and CellHeight contain the size in pixels of each character cell in the grid.
TextFgColorIndex contains an index into the Global Color Table to retrieve the color of the text.
TextBgColorIndex contains a Global Color Table index value to be used as the color for the background of the text.
PlainTextData contains the actual textual information that is to be rendered as a graphic. This field contains one or more sub-blocks of data. Each sub-block begins with a byte that indicates the number of data bytes that follow. From 1 to 255 data bytes may follow this byte. There may be any number of sub-blocks in this field.
Terminator contains the value zero and marks the end of the Plain Text Extension block.
Application Extension blocks contain application-specific information in a way similar to the way tags are used in the TIFF and TGA image file formats. Information not normally found in a GIF-format file may be stored in an Application Extension block and then read by any application that understands how to interpret the data. Any number of Application Extension blocks may appear in a GIF file.
Application Extension data is application-readable only. All data stored in this extension is designed to be acted upon by the software application that is reading and processing the GIF data stream. To store human-readable data the Comment Extension block is used instead (see the "Comment Extension block" section).
Examples of data stored in an Application Extension block include instructions on changing video modes, applying special processing to displayed image data, and storing additional color tables. Information used to control the computer platform executing the application can also be stored. This can include information on how to manipulate files, how to access peripheral devices such as modems and printers, and how to send audible signals to the audio speaker.
The Application Extension block is 14 bytes in length and has the following structure:
typedef struct _GifApplicationExtension { BYTE Introducer; /* Extension Introducer (always 21h) */ BYTE Label; /* Extension Label (always FFh) */ BYTE BlockSize; /* Size of Extension Block (always 0Bh) */ CHAR Identifier[8]; /* Application Identifier */ BYTE AuthentCode[3]; /* Application Authentication Code */ BYTE *ApplicationData; /* Point to Application Data sub-blocks */ BYTE Terminator; /* Block Terminator (always 0) */ } GIFAPPLICATION;
Introducer contains the value 21h and is used to identify the start of a Extension data block.
Label contains the value FFh and is used to identify this block of data as an Application Extension.
BlockSize contains the value 0Bh, which is the number of bytes in the Identifier and AuthentCode fields.
Identifier may contain up to eight printable 7-bit ASCII characters. These characters are used to identify the application that wrote the Application Extension block. If this identifier value is recognized, the remaining portion of the block is read and its data acted upon. If the identifier value is not recognized, the remaining portion of the block is read and its data is discarded.
AuthentCode contains a value that is used to uniquely identify a software application that created the Application Extension block. This field may contain a serial number, a version number, or a unique binary or ASCII code used to identify an individual software application or computer platform. This field may be used to allow only specific copies or revisions of a particular software application to access the data in certain Application Extension blocks.
ApplicationData contains the information that is used by the software application. This field is structured in a series of sub-blocks identical to the data found in a Plain Text Extension block.
Terminator contains the value zero and marks the end of the Application Extension block.
To understand how a GIF reader could interpret Application Extension block information, consider the following example.
An application reading a GIF file comes across an Application Extension. The Identifier field contains the characters "CHKDATE". This identifier is recognized by the application reading the GIF file. The AuthentCode field contains the value "UNX", which is an indication that only versions of this software application running under the UNIX operating system should use the data in this block. All versions of the program not running under UNIX should ignore this block.
The application reading this GIF file knows that a CHKDATE block holds a 2-byte date stamp in the ApplicationCode field. If the current system date is not the same as this date stamp value, the next Graphics Rendering block should not be displayed. The count byte is read from the data sub-block and then the two-byte stamp value. The Terminator field value follows this stamp value.
A second Application Extension is read containing the identifier "CLRSCRN". The application recognizes this identifier and knows that it is an instruction for the display screen to be cleared immediately. The AuthentCode field is not used in this block and its value is read and ignored. This block also does not contain any data sub-blocks, and therefore the block terminator value occurs immediately.
A third Application Extension is read containing the identifier "SOUNDBYT". This identifier informs the application that this block contains audio data that should be sent to the sound card driver installed in the system. The AuthentCode field contains the code "CDI", which indicates the format of the audio data stored in this block. If the AuthentCode field is recognized, then the data sub-blocks are read, and the data is sent to the computer platform's audio system until a zero count byte is read.
Finally, a fourth Application Extension is read containing the identifier "SPECIAL". This particular identifier is not recognized by the application reading the GIF file, so the AuthentCode field and the ApplicationData field are read and ignored.
The above examples are only a few of the hundreds of ways Application Extension blocks may be used to provide control over a computer system and the way GIF images are displayed. The GIF89a specification does not list any specific examples of the use of Application Extension blocks, nor does it include a standard list of identifiers; presumably, this is left up to the ingenuity of the developer.
The Comment Extension block is used to insert a human-readable string of text into a GIF file or data stream. Each comment may contain up to 255 7-bit ASCII characters, including all the ASCII control codes. Any number of Comment Extension blocks may occur in a GIF file, and they may appear anywhere after the Global Color Table. It is suggested, however, that comments should appear before or after all image data in the GIF file.
All data stored in the Comment Extension is designed to be read only by the human user examining a GIF file or data stream. All comment data should be ignored by the application reading the GIF data stream. To store computer-readable data and instructions, use the Application Extension block. (See the section called "Application Extension block" earlier in this article.)
Comments are typically used to identify the source of the GIF image, its author, the creating software, the creation time and date, the copyright notice for the image data, and so on. Several image display programs that accommodate version 89a images also have the capability of displaying comment data stored within the GIF files.
Comment Extension blocks must always remain independent of all other data in a GIF file. Comment Extension data is not modified by the information in any other Extension blocks, and comments should not contain data that is intended to be read and interpreted as instructions by software applications.
The Comment Extension block may vary from 5 to 259 bytes in length and has the following structure:
typedef struct _GifCommentExtension { BYTE Introducer; /* Extension Introducer (always 21h) */ BYTE Label; /* Comment Label (always FEh) */ BYTE *CommentData; /* Pointer to Comment Data sub-blocks */ BYTE Terminator; /* Block Terminator (always 0) */ } GIFCOMMENT;
Introducer contains the value 21h and is used to identify the start of a Extension data block.
Label contains the value FEh and is used to identify this block of data as a Comment Extension.
CommentData contains one or more sub-blocks of ASCII string data. The character strings stored in the CommentData field sub-blocks are not required to be NULL-terminated.
Terminator contains the value 0 and marks the end of the Comment Extension block. The value of the Terminator field may be used as a NULL-terminator if "size + 1" bytes of comment data is read from the block.
For further information about GIF, see the specifications included on the CD-ROM:
CompuServe Incorporated, GIF Graphics Interchange Format: A standard defining a mechanism for the storage and transmission of bitmap-based graphics information. Columbus, OH, 1987.
CompuServe Incorporated, Graphics Interchange Format: Version 89a. Columbus, OH, 1990.
You can also obtain a copy of the GIF89a specification from many BBSs and online services, or directly from CompuServe at:
CompuServe Incorporated
Attn: Graphics Technology Department
5000 Arlington Center Boulevard
Columbus, OH 43220
Voice: 614-457-8600
Voice: 800-848-8199
WWW: http://www.compuserve.com/
Several packages included on the CD-ROM display and convert GIF images.
[Previous]
[Next]
[Up]
[Index]
Contents |
Glossary |
Main |
Formats |
Software |
Internet |
Book
Copyright © 1996, 1994 O'Reilly & Associates, Inc. All Rights Reserved.