Home for HMNL Enterprise Computing

Are GIF Images Really Limited To 256 Colours?

Ian Tree  02 December 2015 21:16:26
There has been quite some debate on this topic over the years, much of it peppered with misunderstanding, misinformation and downright netbollox. In this article we take a fresh look at the question from the point of view of the words and intentions of the GIF specifications and the conformance of implementations in different codecs.

Specifications



There are two different versions of the GIF specification, the first identified as “87a” was issued in 1987 and this was followed by the “89a” version in 1989.
The 1987 specification describes two key features that have an impact on the maximum colours question. First an image file or stream may contain multiple separate images and secondly each image can specify a separate colour map. Appendix D of the specification makes it clear how codecs are expected to implement a stream that is encoded with separate images.

"Since a GIF data stream can contain multiple images, it is necessary to describe processing and display of such a file.  Because the image descriptor allows for placement of  the image within  the logical screen, it is possible to define a sequence of images that may each be a partial screen, but in total fill the entire screen.   The guidelines for handling the multiple image situation are:

1.  There is no pause between images.  Each is processed immediately as seen by the decoder.

2.  Each image explicitly overwrites any image already on the screen inside of its window.  The only screen clears are at the beginning and end of the GIF image process.   See discussion on the GIF terminator.”



It is clear that the specification supports composite images both through tiling and through overlaying. Given that each image (or tile) supports a separate colour map each containing up to 256 individual colours it is clear that even in the 87a specification images with more than 256 colours are supported, providing that the colour distribution in the image is such that it can be broken down into sub-images (or tiles) with each tile limited to 256 colours. In theory any image with any number of colours can be decomposed into tiles or overlays (or a combination of both) using sub-images as small as a single pixel, however, such an implementation may not be realistic.

It must now be stated that extending the colour palette of an image through the use of composite tiles or overlays was not foreseen at the time of writing the specification. The part of the specification that describes the use of Local (per image) colour maps states the following.

“A Local Color Map is optional and defined here for future use.”



The 89a specification, published in 1989 was intended to extend the original 87a specification as can be seen from the foreword of that document.

“This document defines the Graphics Interchange Format(sm). The specification given here defines version 89a, which is an extension of version 87a.”



Although the text of the “Appendix D” from the 87a specification does not appear in the 89a version, there is no text that negates the continued validity and applicability of the appendix. Multiple (sub) images in a single GIF stream or file are still recognized as can be seen from the section defining the “Image Descriptor” block.

“Exactly one Image Descriptor must be present per image in the Data Stream.  An unlimited number of images may be present per Data Stream.”



The 89a specification introduced the (per image) Graphics Control Extension (GCE);  a generic mechanism for implementing an extension was defined in the 87a specification.

“The Graphic Control Extension contains parameters used when processing a graphic rendering block. The scope of this extension is the first graphic rendering block to follow. The extension contains only one data sub-block.

This block is OPTIONAL; at most one Graphic Control Extension may precede a graphic rendering block. This is the only limit to the number of Graphic Control Extensions that may be contained in a Data Stream.”



It should be noted that although the GCE block is optional the “Version Number” section of the 89a specification states the following.

“The encoder should make every attempt to use the earliest version number covering all the blocks in the Data Stream; the unnecessary use of later version numbers will hinder processing by some decoders.”



The GCE introduced three new fields all of which are relevant to the discussion about the number of colours limitation in GIF images. The first field is the “Delay Time” which is described as follows.

“Delay Time - If not 0, this field specifies the number of hundredths (1/100) of a second to wait before continuing with the processing of the Data Stream. The clock starts ticking immediately after the graphic is rendered.”



The delay time field allows a stream containing multiple images to be rendered as an animation. There is a clear implication that a value of zero for the field would elicit the behaviour described in Appendix D of the 87a specification, rendering the next image in the stream immediately after the current one has been rendered.

The second field is a packed field of which 3 bits are used to describe the disposition of the image which is described as follows.

“Disposal Method - Indicates the way in which the graphic is to be treated after being displayed.

Values :        0 -   No disposal specified. The decoder is not required to take any action.

               1 -   Do not dispose. The graphic is to be left in place.

               2 -   Restore to background color. The area used by the graphic must be restored to the background color.

               3 -   Restore to previous. The decoder is required to restore the area overwritten by the graphic with what was there prior to rendering the graphic.

                4-7 -    To be defined.”



The value of 1 “Do not dispose” follows the processing described in Appendix D of the 87a specification.

The last new field of interest is the “Transparency Index” and the corresponding flag in the packed fields, described as follows.

“Transparency Index - The Transparency Index is such that when encountered, the corresponding pixel of the display device is not modified and processing goes on to the next pixel. The index is present if and only if the Transparency Flag is set to 1.”



It may not be immediately obvious how this field relates to the maximum colours question. Allowing a transparent colour to be used in an image removes any restriction on colours and their distribution, any image with any number of colours can be decomposed into a series of overlaid images using a transparent colour in all but the first image.

In conclusion the GIF specifications do and always have supported mechanisms that allow for encoding images with an unlimited number of colours.

Implementations



This section looks at the implementation of the specification in a few illustrative codecs to see if they constrain the maximum number of colours in practical use.

GIF 87a Tiled Image Behaviour



A GIF image was prepared with 200 (20 x 10) images, each image 20 x 20 pixels tiling a 400 x 200 logical screen. Each tile uses a different colour index in a Global Colour Map. The image is marked with a version identifier of “87a”.  The image is then viewed in different software applications to see how their respective codecs perform.

MS Edge and MS IE 11 both only display the first image out of 200, interestingly MS Paint displays the complete 200 tile image. Google Chrome (on Windows 10) displays the complete 200 tile image, however, it treats the image stream as an animation and enforces a default minimum delay time on each image in the stream taking approximately 20 seconds to render the complete image (10/100ths sec delay time). Mozilla Firefox displays the complete 200 tile image without any rendering delays.

Of the codecs tested only Mozilla Firefox conforms to Appendix D of the 87a specification.
GIF 87a Image - 200 Tiles
GIF 87a Image - 200 Tiles


GIF 89a Tiled Image Behaviour



A GIF image was prepared with 200 (20 x 10) images, each image 20 x 20 pixels tiling a 400 x 200 logical screen. Each tile uses a different colour index in a Global Colour Map and specifies a delay time of 0 in the GCE. The image is marked with a version identifier of “89a”.  The image is then viewed in different software applications to see how their respective codecs perform.

MS Edge, MS IE 11 and Google Chrome all display the complete 200 tile image as an animation with an enforced delay on each image. All three codecs took about 20 seconds to render the complete animation, implying a default delay time of 10/100ths seconds per image. Mozilla Firefox displays the complete 200 tile image without any rendering delays.

Again only the Mozilla Firefox codec conformed to the expectation that a zero delay time in a GCE would induce the behaviour as laid out in Appendix D of the 87a specification.
GIF 89a Image - 200 Tiles
GIF 89a Image - 200 Tiles


GIF89a Tiled Animation



A GIF 89a Image was prepared identical to that used in the previous experiment, except that the delay time set in each GCE was set to 20 (20/100ths of a second). The image is then viewed in different software applications to see how their respective codecs perform.

All four codecs displayed the complete 200 tile image, taking 40 seconds to complete the rendering process. All codecs conform to the behaviour expected from the 89a specification.
GIF 89a Animation - 200 Tiles
GIF 89a Animation - 200 Tiles



GIF 89a Tiled 512 Colour Image Behaviour



A GIF 89a Image was prepared with two side-by-side images (tiles), each tile was populated with a 16 x 16 grid of squares, each square 20 x 20 pixels of a different colour, thus the complete image should render 512 different colours. One tile used a Global Colour Map and the other a Local Colour Map. Both images had a GCE with a delay time set to zero. The image is then viewed in different software applications to see how their respective codecs perform.

MS Edge, MS IE 11 and Google Chrome all display the complete image with all 512 colours, there was no perceptible delay visible during rendering. From the previous examples these three codes will have treated the image as an animation and would have enforced a 10/100ths of a second delay between the first and second tile but this delay would not be visible during rendering. Mozilla Firefox rendered the image correctly with delay in the rendering.

The behaviour of all codecs was as would be expected from the previous experiments.
GIF 89a Image - 512 colours
GIF 89a Image - 512 colours


Off Topic



The GIF 89a specification introduced the Application Extension which provided a mechanism for individual application to store additional persistent information in the GIF image stream. This extension mechanism was used by Netscape to add a field that controls how many times the render mechanism will “play” an animation. This extension is recognised by all of the codecs in common use and all agree that a value of zero for the field means that the animation should be played continuously until the image is dismissed. They also agree that if the extension is not present then the animation is played only once. They do not agree on the meaning of the field when the value is non-zero, with some using the field value as an iteration counter for the render loop where a value of one causes the animation to be played once while others take it as a repeat counter where a value of one causes the animation to be played once and repeated once, therefore played twice. Unfortunately documentation is unclear on which interpretation is correct, both are equally valid. It should be noted that most common use is to play once or play continuously therefore omitting the extension to play once and setting a count of zero to play continuously will work in most codecs.

Conclusion



In theory a GIF image can support an unlimited (or rather limited only by the supported colour encoding which is 24 bit RGB - RGB888) number of colours. However, the implementation in a number of codecs that are in common use does put practical limits on the number of different colours that can be displayed, this limit is however far in excess of 256. The rendering time for a GIF image stream that contains multiple images as tiles or overlays is entirely dictated by the minimum default image delay time set by non-conforming codecs. The delay time imposed by all of the non-conforming codecs that were examined is 10/100ths of a second. It is therefore possible to budget for that delay and set a maximum number of colours that can be used in practice accordingly. If a total render time of three seconds is considered to be acceptable then this would allow for 30 separate images in the stream this would permit 30 * 255 = 7,650 different colours to be comfortably displayed in an image.

MS Edge and MS IE 11 are considered non-conforming to the GIF 87a specification as they do not recognize multiple images in a single image stream. Google Chrome is considered non-conforming to the GIF 87a specification as it does not follow Appendix D and treats the multiple in-stream images as an animation and imposes a minimum image delay time. Mozilla Firefox is considered as conforming to the GIF 87a specification.

MS Edge, MS IE 11 and Google Chrome are all considered as non-conforming to the GIF 89a specification as they all impose a minimum image delay time for in-stream images that have a delay time of zero specified in the Graphics Control Extension block. The Mozilla Firefox codec is considered as conforming.

It must be said that given the stricter conformance of the Mozilla Firefox codec, in the areas considered, they would also get my vote for the most logical implementation of the Netscape Application Extension iteration count.
Comments