The GIF File Format - A Quick Reference For Classic ASP Programmers
| Overview - The Anatomy of a GIF | ||
| 6 bytes | Required | Header |
| 7 bytes | Required | Logical Screen Descriptor |
| Max 768 bytes | Optional | Global Color Table |
| 10 bytes | Required | Local Image Descriptor: Starts with byte &H2C. |
| n bytes | Optional | Graphic Control Extension: Starts with bytes &H21 and &HF9. | n bytes | Optional | Application Block Extension: Starts with bytes &H21 and &HFF. Unlimited number of sub blocks allowed. |
| n bytes | Optional | Comment Block Extension: Starts with bytes &H21 and &HFE. Unlimited number of sub blocks allowed. |
| n bytes | Optional | Plain Text Extension: Starts with bytes &H21 and &H01. Unlimited number of sub blocks allowed. |
| 1 byte | Required | Terminator: &H3B |
| This GIF image demonstrates the Application Extension Block and the Comment Extension Block. Save this file to disk and view it in a text editor. | ![]() |
| Here's an example of an animated GIF: |
All GIF images start with a header 6 bytes long:
| The Gif File Header | |||
| 1 | G | 1 byte | First 3 bytes contains the GIF signature: GIF |
| 2 | I | 1 byte | |
| 3 | F | 1 byte | |
| 4 | 8 | 1 byte | Next 3 bytes contains the GIF Version: 87a or 89a |
| 5 | 9 | 1 byte | |
| 6 | a | 1 byte | |
If AscB(MidB(GIFByteArray, 1, 1)) = 71 And AscB(MidB(GIFByteArray, 2, 1)) = 73 And AscB(MidB(GIFByteArray, 3, 1)) = 70 Then
'// We have found a GIF signature
End If
Directly after the GIF header comes the Logical Screen Descriptor. This is 7 bytes.
| Logical Screen Descriptor | ||
| 1 | 1 byte | 2 bytes: Logical Screen Width |
| 2 | 1 byte | |
| 3 | 1 byte | 2 bytes: Logical Screen Height |
| 4 | 1 byte | |
| 5 | 1 byte | Packed Field |
| 6 | 1 byte | Background Color Index |
| 7 | 1 byte | Pixel Aspect Ratio |
- Logical Screen Width: Width of image in pixels.
- Logical Screen Height: Height of image in pixels.
- Packed Field.
- Background Color Index: a value pointing to a color in the Global Color Table.
- Pixel Aspect Ratio: A factor used to calculate an approximation of the aspect ratio of the pixel in the GIF image.
Image Width:
lWidth = CLng(AscB(MidB(GIFByteArray, 7, 1)) + (AscB(MidB(GIFByteArray, 8, 1)) * 256))
Image Height:
lHeight = CLng(AscB(MidB(GIFByteArray, 9, 1)) + (AscB(MidB(GIFByteArray, 10, 1)) * 256))
Packed Field:
This byte contains the following information:
Global Color Table Flag = 1 Bit
Color Resolution = 3 Bits
Sort Flag = 1 Bit
Size of Global Color Table = 3 Bits
Here's an example of a GIF image opened in a hex editor. The highlighted byte 11 is the "packed" byte:

The bit pattern for this byte:
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 |
- Bit 7 is the Global Color Table Flag. If this is 1 there is a Global Color Table present:
If AscB(MidB(GIFByteArray, 11, 1)) And 128 Then bGlobalColorTableFlag = True- Bit 6 - 4 contain the Color Resolution.
lColorDepth = 2 ^ ((Asc(CStr(AscB(MidB(GIFByteArray, 11, 1)))) And 7) + 1)- Bit 3 is the Sort Flag: Indicates whether the Global Color Table is sorted or not.
- Bit 0 - 2 contain the size of the Global Color Table.
If AscB(MidB(GIFByteArray, 11, 1)) And 4 Then lngGlobalColorFactor = 4
If AscB(MidB(GIFByteArray, 11, 1)) And 2 Then lngGlobalColorFactor = lngGlobalColorFactor Or 2
If AscB(MidB(GIFByteArray, 11, 1)) And 1 Then lngGlobalColorFactor = lngGlobalColorFactor Or 1
lSizeGlobalColorTable = CLng(3 * (2 ^ (lngGlobalColorFactor + 1)))
Background Color Index:
The Background Color is the color used for those pixels on the screen that are not covered by an image.
Aspect Ratio:
Aspect Ratio = (Pixel Aspect Ratio + 15) / 64
A Color Table is a color palette. If the Global Color Table Flag is set, then this table will follow immediately after the Local Image Descriptor. If this flag is not set, then there should be a local color table contained with the image data itself. (See below). In this case we have a Global Color Table and it always starts at byte number 14. The byte pattern is like this:
| Global Color Table | |
| 1 byte | Red(0) |
| 1 byte | Green(0) |
| 1 byte | Blue(0) |
| 1 byte | Red(1) |
| 1 byte | Green(1) |
| 1 byte | Blue(1) |
| .... | Max 768 bytes/256 color triplets |
After the GIF header, the Logical Screen Descriptor and the Global Color Table, we find the actual image data. There might be an unlimited number of images present in a GIF. Each image frame is composed of a Local Image Descriptor, an optional Local Color Table, and the image data. One Image Descriptor must be present per image.
| Local Image Descriptor | ||
| 1 byte | &H2C | Identifies the beginning of an Image Descriptor. |
| 2 bytes | Image Left Position | |
| 2 bytes | Image Top Position | |
| 2 bytes | Width of the image in pixels. | |
| 2 bytes | Height of the image in pixels. | |
| 1 byte | Packed field. | |
Packed field:
Local Color Table Flag = 1 bit
Interlace Flag = 1 bit
Sort Flag = 1 bit
Reserved = 2 bits
Size of Local Color Table = 3 bits
- Bit 7 is the Local Color Table Flag. Indicates the presence of a Local Color Table immediately following this Image Descriptor.
- Bit 6 is the Interlace Flag. Indicates if the image is interlaced.
- Bit 5 is the Sort Flag. Indicates whether the Local Color Table is sorted.
- Bit 4 - 3: Reserved.
- Bit 2 - 0: Size of Local Color Table
If the Local Color Table Flag is set, then the Local Color Table will follow immediately after this block. Then follows the image data.
A GIF89a may contain different Extension Blocks which are all optional. They may appear anywhere in the GIF file, in no specific order and there might be more than just one of each type. In fact, the number is unlimited. This means you might store the complete works of Shakespeare inside the Comment Extension in one single GIF file. All Extension Blocks start with hex value &H21. The byte following is the Extension Label identifying the type of Extension Block.
The information stored in a Graphics Control block is used to modify how the GIF image is displayed. One block is controlling one image frame.
| Graphics Control Extension | ||
| 1 byte | &H21 | Extension Block Identifier |
| 1 byte | &HF9 | Extension Label |
| 1 byte | &H04 | Fixed value of 4 which is the length of the following block. |
| 1 byte | Packed field. | |
| 2 bytes | Delay Time: Hundredths of seconds to wait. | |
| 1 byte | Transparent Color Index | |
| 1 byte | &H0 | The block is terminated by a &H0 value. |
Packed Field:
This byte contains the following information:
Reserved= 3 Bits
Disposal Method= 3 Bits
User Input Flag= 1 Bit
Transparent Color Flag = 1 Bit
- Bit 7 - 5: Reserved. Always 0.
- Bit 4 - 2: "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)."
- Bit 1: If the User Input Flag is set then user input (key press, mouse click, and so forth) is expected before continuing to the next graphic sequence.
- Bit 0: Transparent Color Flag. If this flag is set then the Transparent Color Index byte will contain an index value for the transparent color.
| Application Block Extension | ||
| 1 byte | &H21 | Extension Block Identifier |
| 1 byte | &HFF | Extension Label |
| 1 byte | Fixed value of 11 which is the length of the following block. | |
| 8 bytes | Application Identifier: 8 bytes of Ascii characters. | |
| 3 bytes | Application Authentic Code: 3 bytes of Ascii characters. | |
| 1 byte | n | Length of the following Application Data Block. |
| n bytes | Max 256 bytes | Application Data Block. The number of sub blocks are unlimited. |
| 1 byte | &H0 | The block is terminated by a &H0 value. |
The Application Identifier field is meant to identify the originating owner application. The Application Authentic Code field is meant to identify the version number of this application. You could use these fields to write hidden copyright information:
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | ||||||
| &H21 | &HFF | 11 | M | Y | F | O | O | A | P | P | 1 | . | 5 | n | Length of Application Data is n bytes. | &H0 |
Here's an example seen with a hex editor:

The Application Identifier field reads: "GIFInfo!". The Application Authentic Code field reads: "1.0". The Application Data field reads: "Hello world!".
The Comment Extension Block is another optional GIF Block. It is used to store any length of Ascii strings in sub blocks of max 256 characters.
| Comment Block Extension | 1 byte | &H21 | Extension Block Identifier |
| 1 byte | &HFE | Extension Label |
| 1 byte | n | Length of the following Comment Block. |
| n bytes | Max 256 bytes | The Comment Block. The number of sub blocks are unlimited. |
| 1 byte | &H0 | The block is terminated by a &H0 value. |
Example of a Comment extension Block in a GIF file. The byte highlighted is the Extension Identifier &H21 followed by the Extension Label &HFE:

| &H21 | &HFE | n | Length of Comment Block is n bytes. | &H0 |
The Plain Text Extension Block allows for displaying printable 7-bits Ascii characters over the actual image, a primitive watermark. The text is rendered in a grid system with each character put in a cell. (This feature is not supported by any major piece of software that I know of.)
| Plain Text Extension | ||
| 1 byte | &H21 | Extension Block Identifier |
| 1 byte | &H01 | Extension Label |
| 1 byte | Fixed value of 12 which is the length of the following block. | |
| 1 | 2 bytes | StartX: Defines the start left position for the text grid. |
| 2 | ||
| 3 | 2 bytes | StartY: Defines the start top position for the text grid. |
| 4 | ||
| 5 | 2 bytes | Width of text grid in pixels. |
| 6 | ||
| 7 | 2 bytes | Height of text grid in pixels. |
| 8 | ||
| 9 | 1 byte | Width of grid cell for a single character. |
| 10 | 1 byte | Height of grid cell for a single character. |
| 11 | 1 byte | Index for the color of the characters. |
| 12 | 1 byte | Index for the background color of the characters. |
| 1 byte | n | Length of the following sub block of text. |
| n bytes | Max 256 bytes | The Text block. Unlimited number of sub blocks allowed. |
| 1 byte | &H0 | The block is terminated by a &H0. |
Some Classic ASP code to get you started:
'------------------------------------------------------------------------------------------------------------
' Comment: Read GIF into a byte array.
'------------------------------------------------------------------------------------------------------------
Private Function LoadGIFAsBytes(sFullPath)
On Error Resume Next
Dim oStream
If IsEmpty(oStream) Then Set oStream = Server.CreateObject("ADODB.Stream")
With oStream
.Type = 1 '// adTypeBinary
.Open
.LoadFromFile sFullPath
GIFByteArray = .Read
End With
oStream.Close
Set oStream = Nothing
LoadGIFAsBytes = (LenB(GIFByteArray) > 0 And Err.Number = 0)
End Function
'------------------------------------------------------------------------------------------------------------
' Comment: Loop the GIF bytes and look for a Comment Extension Block.
'------------------------------------------------------------------------------------------------------------
Private Function ParseGIF()
On Error Resume Next
Dim i, k, sComment
For i = 1 To m_lImageSize
If AscB(MidB(GIFByteArray, i, 1)) = 33 Then
If AscB(MidB(GIFByteArray, i + 1, 1)) = 254 Then
For k = i To m_lImageSize
sComment = sComment & Chr(AscB(MidB(GIFByteArray, k, 1)))
If AscB(MidB(GIFByteArray, k, 1)) = 0 Then Exit Function
Next
End If
End If
Next
ParseGIF = (Err.Number = 0)
End Function
'------------------------------------------------------------------------------------------------------------
' Comment: Save byte array to GIF.
'------------------------------------------------------------------------------------------------------------
Private Sub SaveAsGIF(ByteArray, sSavePath)
On Error Resume Next
Dim oStream
If IsEmpty(oStream) Then Set oStream = Server.CreateObject("ADODB.Stream")
With oStream
If .State = 1 Then .State = 0 '// adStateOpen = 1: adStateClosed = 0
.Type = 1 '// adTypeBinary
Call .Open
Call .Write(ByteArray)
Call .SaveToFile(sSavePath, 2) '// adSaveCreateOverWrite
Call .Close
End With
Set oStream = Nothing
End Sub
GIF LINKS:
http://en.wikipedia.org/wiki/GIF
http://www.w3.org/Graphics/GIF/spec-gif89a.txt
http://semmix.pl/color/exgraf/eeg10.htm
http://www.u229.no/stuff/GIFInfo/
http://www.u229.no/stuff/GIFText/
