Blame doc/whatsinagif/lzw_image_data.html

Packit f1137c
Packit f1137c
Packit f1137c
<html>
Packit f1137c
<head>
Packit f1137c
<title>What's In A GIF - LZW Image Data</title>
Packit f1137c
<style type="text/css">
Packit f1137c
.byte {font-family: Courier, fixed;
Packit f1137c
	padding: .2em}
Packit f1137c
.gif_header {background-color: #f9E89D}
Packit f1137c
.gif_screen {background-color: #C8DBD9}
Packit f1137c
.gif_color {background-color: #E1E1E1}
Packit f1137c
.gif_graphic {background-color: #F9EB9D}
Packit f1137c
.gif_imgdesc {background-color: #C2D1DC}
Packit f1137c
.gif_imgdata {background-color: #D0C4C4}
Packit f1137c
.gif_trailer {background-color: #f9E89D}
Packit f1137c
.gif_ext {background-color: #D0CFAE}
Packit f1137c
#global_color_size {margin-left: auto; margin-right:auto; border:1px solid black;}
Packit f1137c
#global_color_size th {border-bottom: 1px solid #666666}
Packit f1137c
#global_color_size td {text-align:center;}
Packit f1137c
.code_table {margin-left: auto; margin-right:auto; border:1px solid black;}
Packit f1137c
.code_table th {text-align: left; border-bottom: 1px solid #666666}
Packit f1137c
.alg_steps {margin: 0 auto; border: 1px solid black}
Packit f1137c
.alg_steps th, .alg_steps td {border: 1px solid black}
Packit f1137c
.alg_steps .index {padding: 0 .3em}
Packit f1137c
.alg_steps .processed {color: #CCC}
Packit f1137c
.alg_steps .buffer {background: #C8DBD9 url(highlight_green.gif) repeat-x center left;
Packit f1137c
	border-top: 1px solid #AAA2A2; border-bottom: 1px solid #AAA2A2;}
Packit f1137c
.alg_steps .current {background: #D0C4C4 url(highlight_purple.gif) repeat-x center left;
Packit f1137c
	border-top: 1px solid #98A5A4; border-bottom: 1px solid #98A5A4;}
Packit f1137c
</style>
Packit f1137c
</head>
Packit f1137c
<body>
Packit f1137c
Packit f1137c
Packit f1137c

What's In A GIF

Packit f1137c
Packit f1137c
(LZW image data)
Packit f1137c
Packit f1137c
Packit f1137c
Packit f1137c
Packit f1137c
Packit f1137c

Back to the GIF index page.

Packit f1137c
Packit f1137c
Packit f1137c

Now let's look at exactly how we go about storing an image in a GIF

Packit f1137c
file. The GIF format is a raster format, meaning it stores image data
Packit f1137c
by remembering the color of every pixel in the image. More
Packit f1137c
specifically, GIF files remember the index of the color in a color
Packit f1137c
table for each pixel. To make that clearer, let's review the
Packit f1137c
sample image we used in the first
Packit f1137c
section.

Packit f1137c
Packit f1137c
Packit f1137c
Packit f1137c
Packit f1137c

Actual Size

Packit f1137c
Packit f1137c
width="10" height="10" style="padding: 20px" />
(10x10)
Packit f1137c
Packit f1137c

Enlarged

Packit f1137c
Packit f1137c
title="Enlarged" width="100" height="100" />
(100x100)
Packit f1137c
Packit f1137c

Color Table

Packit f1137c
Packit f1137c
IndexColor
Packit f1137c
0White
Packit f1137c
1Red
Packit f1137c
2Blue
Packit f1137c
3Black
Packit f1137c
Packit f1137c
Packit f1137c
Packit f1137c
Packit f1137c

The color table came from the global color table block. The colors

Packit f1137c
are listed in the order which they appear in the file. The first color
Packit f1137c
is given an index of zero. When we send the codes, we always start at
Packit f1137c
the top left of the image and work our way right. When we get to the
Packit f1137c
end of the line, the very next code is the one that starts the next
Packit f1137c
line. (The decoder will "wrap" the image based on the image
Packit f1137c
dimensions.) We could encode our sample image in the following
Packit f1137c
way:

Packit f1137c
Packit f1137c

1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1,

Packit f1137c
1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 1, 1, 1,
Packit f1137c
0, 0, 0, 0, 2, 2, 2, ...

Packit f1137c
Packit f1137c

The above listing shows the sequence required to render the first five

Packit f1137c
lines of the image. We could continue with this method until we've
Packit f1137c
specified the color for every pixel; however, this can result in a
Packit f1137c
rather large file. Luckily for us, the GIF format allows us to take
Packit f1137c
advantage of repetition in our output and to compress our data.

Packit f1137c
Packit f1137c

Much of the following information came from John Barkaus's tutorial

Packit f1137c
LZW and GIF Explained, which seems to have fallen off the
Packit f1137c
web.  I've tried to provide more detailed samples as well
Packit f1137c
as illustrations to make the process even clearer

Packit f1137c
Packit f1137c

LZW Compression

Packit f1137c
Packit f1137c

The compression method GIF use is a variant of LZW

Packit f1137c
(Lempel-Ziv-Welch) compression. To start using this method, we need a
Packit f1137c
code table. This code table will allow us to use
Packit f1137c
special codes to indicate a sequence of colors rather than just one at
Packit f1137c
a time.  The first thing we do is to initialize the code
Packit f1137c
table.  We start by adding a code for each of the colors in the
Packit f1137c
color table. This would be a local color table if one was provided, or
Packit f1137c
the global color table. (I will be starting all codes with
Packit f1137c
"#" to distinguish them from color indexes.)

Packit f1137c
Packit f1137c
Packit f1137c
CodeColor(s)
Packit f1137c
#00
Packit f1137c
#11
Packit f1137c
#22
Packit f1137c
#33
Packit f1137c
#4Clear Code
Packit f1137c
#5End Of Information Code
Packit f1137c
Packit f1137c
Packit f1137c

I added a code for each of the colors in the global color table of

Packit f1137c
our sample image. I also snuck in two special control codes.  (These
Packit f1137c
special codes are only used in the GIF version of LZW, not in standard
Packit f1137c
LZW compression.) Our code table is now considered initialized.

Packit f1137c
Packit f1137c

Let me now explain what those special codes are for. The first new code

Packit f1137c
is the clear code (CC). Whenever you come across the clear code 
Packit f1137c
in the image data, it's your cue to reinitialize the code table. (I'll 
Packit f1137c
explain why you might need to do this in a bit.) The second new code 
Packit f1137c
is the end of information code (EOI). When you come across 
Packit f1137c
this code, this means you've reached the end of the image. Here I've placed
Packit f1137c
the special codes right after the color codes, but actually the value of
Packit f1137c
the special codes depends on the value of the LZW minimum code size
Packit f1137c
from the image data block. If the LZW minimum code size is the same as
Packit f1137c
the color table size, then special codes immediatly follow the colors; however
Packit f1137c
it is possible to specify a larger LWZ minimum code size which may leave
Packit f1137c
a gap in the codes where no colors are assigned. This can be
Packit f1137c
summarizaed in the following table.

Packit f1137c
Packit f1137c
Packit f1137c
Packit f1137c
LWZ Min Code
SizeColor
CodesClear
CodeEOI
Code
Packit f1137c
2#0-#3#4#5
Packit f1137c
3#0-#7#8#9
Packit f1137c
4#0-#15#16#17
Packit f1137c
5#0-#31#32#33
Packit f1137c
6#0-#63#64#65
Packit f1137c
7#0-#127#128#129
Packit f1137c
8#0-#255#256#257
Packit f1137c
Packit f1137c
Packit f1137c
Packit f1137c

Before we proceed, let me define two more terms. First the index

Packit f1137c
stream will be the list of indexes of the color for each of 
Packit f1137c
the pixels. This is the input we will be compressing. The code 
Packit f1137c
stream will be the list of codes we generate as output. The
Packit f1137c
index buffer will be the list of color indexes
Packit f1137c
we care "currently looking at." The index buffer will contain a list
Packit f1137c
of one or more color indexes. Now we can step though the LZW 
Packit f1137c
compression algorithm. First, I'll just list the steps. After that
Packit f1137c
I'll walk through the steps with our specific example.

Packit f1137c
Packit f1137c
    Packit f1137c
  • Initialize code table
  • Packit f1137c
  • Always start by sending a clear code to the code stream.
  • Packit f1137c
  • Read first index from index stream. This value is now the value
  • Packit f1137c
    for the index buffer
    Packit f1137c
  • <LOOP POINT>
  • Packit f1137c
  • Get the next index from the index stream to the index buffer. We will
  • Packit f1137c
    call this index, K
    Packit f1137c
  • Is index buffer + K in our code table?
  • Packit f1137c
  • Yes:
  • Packit f1137c
    	
      Packit f1137c
      	
    • add K to the end of the index buffer
    • Packit f1137c
      	
    • if there are more indexes, return to LOOP POINT
    • Packit f1137c
      	
      Packit f1137c
      Packit f1137c
    • No:
    • Packit f1137c
      	
        Packit f1137c
        	
      • Add a row for index buffer + K into our code table with
      • Packit f1137c
        	the next smallest code
        Packit f1137c
        	
      • Output the code for just the index buffer to our code steam
      • Packit f1137c
        	
      • Index buffer is set to K
      • Packit f1137c
        	
      • K is set to nothing
      • Packit f1137c
        	
      • if there are more indexes, return to LOOP POINT
      • Packit f1137c
        	
        Packit f1137c
        Packit f1137c
      • Output code for contents of index buffer
      • Packit f1137c
      • Output end-of-information code
      • Packit f1137c
        Packit f1137c
        Packit f1137c

        Seems simple enough, right? It really isn't all that bad. Let's

        Packit f1137c
        walk though our sample image to show you how this works. (The steps I
        Packit f1137c
        will be describing are summarized in the following table. Numbers
        Packit f1137c
        highlighted in green are in the index buffer; numbers in purple are
        Packit f1137c
        the current K value.)  We have already initialized our code table. We
        Packit f1137c
        start by doing two things: we output our clear code (#4) to the code
        Packit f1137c
        stream, and we read the first color index from the index stream, 1,
        Packit f1137c
        into our index buffer [Step 0].

        Packit f1137c
        Packit f1137c

        Now we enter the main loop of the algorithm. We read the next index

        Packit f1137c
        in the index stream, 1, into K [Step 1]. Next we see if we have a
        Packit f1137c
        record for the index buffer plus K in the code stream. In this case we
        Packit f1137c
        looking for 1,1. Currently our code table only contains single colors
        Packit f1137c
        so this value is not in there. Now we will actually add a new row to
        Packit f1137c
        our code table that does contain this value.  The next available code
        Packit f1137c
        is #6, we will let #6 be 1,1. Note that we do not actually send this
        Packit f1137c
        code to the code stream, instead we send just the code for the
        Packit f1137c
        value(s) in the index buffer. The index buffer is just 1 and the code
        Packit f1137c
        for 1 is #1. This is the code we output. We now reset the index buffer
        Packit f1137c
        to just the value in K and K becomes nothing. [Step 2].

        Packit f1137c
        Packit f1137c

        We continue by reading the next index into K. [Step 3]. Now K is 1 and the

        Packit f1137c
        index buffer is 1. Again we look to see if there is a value in our code
        Packit f1137c
        table for the buffer plus K (1,1) and this time there is. (In fact we just
        Packit f1137c
        added it.) Therefore we add K to the end of the index buffer and clear out
        Packit f1137c
        K. Now our index buffer is 1,1. [Step 4].

        Packit f1137c
        Packit f1137c

        The next index in the index stream is yet another 1. This is our

        Packit f1137c
        new K [Step 5].  Now the index buffer plus K is 1,1,1 which we do not
        Packit f1137c
        have a code for in our code table. As we did before, we define a new
        Packit f1137c
        code and add it to the code table. The next code would be #7; thus #7
        Packit f1137c
        = 1, 1, 1. Now we kick out the code for just the values in the index
        Packit f1137c
        buffer (#6 = 1,1) to the code stream and set the index buffer to be
        Packit f1137c
        K. [Step 6].

        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	Step
        Packit f1137c
        	Action
        Packit f1137c
        	Index Stream
        Packit f1137c
        	New Code Table Row
        Packit f1137c
        	Code Stream
        Packit f1137c
        	
        Packit f1137c
        Packit f1137c
        	0
        Packit f1137c
        	Init
        Packit f1137c
        	
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	1
        Packit f1137c
        	Read
        Packit f1137c
        	
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	2
        Packit f1137c
        	Not Found
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	#6 - 1, 1
        Packit f1137c
        	#4 #1
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	3
        Packit f1137c
        	Read
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	4
        Packit f1137c
        	Found
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	5
        Packit f1137c
        	Read
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	6
        Packit f1137c
        	Not Found
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	#7 - 1, 1, 1
        Packit f1137c
        	#4 #1 #6
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	7
        Packit f1137c
        	Read
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1 #6
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	8
        Packit f1137c
        	Found
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1 #6
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	9
        Packit f1137c
        	Read
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1 #6
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	10
        Packit f1137c
        	Not Found
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	#8 - 1, 1, 2
        Packit f1137c
        	#4 #1 #6 #6
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	11
        Packit f1137c
        	Read
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1 #6 #6
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	12
        Packit f1137c
        	Not Found 
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	#9 - 2, 2
        Packit f1137c
        	#4 #1 #6 #6 #2
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	13
        Packit f1137c
        	Read
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1 #6 #6 #2
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	14
        Packit f1137c
        	Found 
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1 #6 #6 #2
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	15
        Packit f1137c
        	Read
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1 #6 #6 #2
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	16
        Packit f1137c
        	Not Found
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	#10 - 2, 2, 2
        Packit f1137c
        	#4 #1 #6 #6 #2 #9
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	17
        Packit f1137c
        	Read
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1 #6 #6 #2 #9
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	18
        Packit f1137c
        	Found
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1 #6 #6 #2 #9
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	19
        Packit f1137c
        	Read
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1 #6 #6 #2 #9
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	20
        Packit f1137c
        	Not Found
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	#11 - 2, 2, 1
        Packit f1137c
        	#4 #1 #6 #6 #2 #9 #9
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	21
        Packit f1137c
        	Read
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1 #6 #6 #2 #9 #9
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	22
        Packit f1137c
        	Found
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1 #6 #6 #2 #9 #9
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	23
        Packit f1137c
        	Read
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1 #6 #6 #2 #9 #9
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	24
        Packit f1137c
        	Found
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1 #6 #6 #2 #9 #9
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	25
        Packit f1137c
        	Read
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	 
        Packit f1137c
        	#4 #1 #6 #6 #2 #9 #9
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        	26
        Packit f1137c
        	Not Found
        Packit f1137c
        	1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                2
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1
        Packit f1137c
                1...
        Packit f1137c
        	#12 - 1, 1, 1, 1
        Packit f1137c
        	#4 #1 #6 #6 #2 #9 #9 #7
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c
        Packit f1137c

        I've included a few more steps to help you see the pattern. You

        Packit f1137c
        keep going until you run out of indexes in the index stream. When
        Packit f1137c
        there is nothing new to read, you simply write out the code for
        Packit f1137c
        whatever values you may have in your index buffer.  Finally you should
        Packit f1137c
        send the end-of-information code to the code stream. In this example,
        Packit f1137c
        that code is #5. (View the 
        Packit f1137c
        complete code table.)

        Packit f1137c
        Packit f1137c

        As you can see we dynamically built many new codes for our code

        Packit f1137c
        table as we compressed the data. For large files this can turn into a
        Packit f1137c
        large number of codes. It turns out that the GIF format specifies a
        Packit f1137c
        maximum code of #4095 (this happens to be the largest 12-bit
        Packit f1137c
        number). If you want to use a new code, you have to clear out all of
        Packit f1137c
        your old codes. You do this by sending the clear code (which for our
        Packit f1137c
        sample was the #4). This tells the decoder that you are reinitializing
        Packit f1137c
        your code table and it should too. Then you start building your own
        Packit f1137c
        codes again starting just after the value for your end-of-information
        Packit f1137c
        code (in our sample, we would start again at #6).

        Packit f1137c
        Packit f1137c

        The final code stream would look like this:

        Packit f1137c
        Packit f1137c

        #4 #1 #6 #6 #2 #9 #9 #7 #8 #10 #2 #12 #1 #14 #15 #6 #0 #21 #0 #10 #7 #22 #23

        Packit f1137c
        #18 #26 #7 #10 #29 #13 #24 #12 #18 #16 #36 #12 #5

        Packit f1137c
        Packit f1137c

        This is only 36 codes versus the 100 that would be required without compression.

        Packit f1137c
        Packit f1137c

        LZW Decompression

        Packit f1137c
        Packit f1137c

        At some point we will need to turn this code stream back into

        Packit f1137c
        a picture. To do this, we only need to know the values in the stream
        Packit f1137c
        and the size of the color table that was used. That's it. You remember that
        Packit f1137c
        big code table we built during compression? We actually have enough information
        Packit f1137c
        in the code stream itself to be able to rebuild it.

        Packit f1137c
        Packit f1137c

        Again, i'll list the algorithm and then we will walk though an example. Let

        Packit f1137c
        me define a few terms i will be using. CODE will be current code we're working 
        Packit f1137c
        with. CODE-1 will be the code just before CODE in the code stream. {CODE} 
        Packit f1137c
        will be the value for CODE in the code table. For example, using the code
        Packit f1137c
        table we created during compression, if CODE=#7 then {CODE}=1,1,1. 
        Packit f1137c
        In the same way, {CODE-1} would be the value in the code table for the 
        Packit f1137c
        code that came before CODE. Looking at step 26 from the compression, 
        Packit f1137c
        if CODE=#7, then {CODE-1} would be {#9}, not {#6}, which was 2,2.

        Packit f1137c
        Packit f1137c
          Packit f1137c
        • Initialize code table
        • Packit f1137c
        • let CODE be the first code in the code stream
        • Packit f1137c
        • output {CODE} to index stream
        • Packit f1137c
        • <LOOP POINT>
        • Packit f1137c
        • let CODE be the next code in the code stream
        • Packit f1137c
        • is CODE in the code table?
        • Packit f1137c
        • Yes:
        • Packit f1137c
          	
            Packit f1137c
            	
          • output {CODE} to index stream
          • Packit f1137c
            	
          • let K be the first index in {CODE}
          • Packit f1137c
            	
          • add {CODE-1}+K to the code table
          • Packit f1137c
            	
            Packit f1137c
            Packit f1137c
          • No:
          • Packit f1137c
            	
              Packit f1137c
              	
            • let K be the first index of {CODE-1}
            • Packit f1137c
              	
            • output {CODE-1}+K to index stream
            • Packit f1137c
              	
            • add {CODE-1}+K to code table
            • Packit f1137c
              	
              Packit f1137c
              Packit f1137c
            • return to LOOP POINT
            • Packit f1137c
              Packit f1137c
              Packit f1137c

              Let's start reading though the code stream we've created to show how to

              Packit f1137c
              turn it back into a list of color indexes.  The first value in the code 
              Packit f1137c
              stream should be a clear code. This means we should initialize our code 
              Packit f1137c
              table. To do this we must know how many colors  are in our color table. 
              Packit f1137c
              (This information comes from the first byte in the image data block in 
              Packit f1137c
              the file. More on this later.) Again we will set up codes #0-#3 to be each 
              Packit f1137c
              of the four colors and add in the clear code (#4) 
              Packit f1137c
              and end of information code (#5).

              Packit f1137c
              Packit f1137c

              The next step is to read the first color code. In the following table you

              Packit f1137c
              will see the values of CODE highlighted in purple, and the values for
              Packit f1137c
              CODE-1 highlighted in green. Our first CODE value is #1. We then output
              Packit f1137c
              {#1}, or simply 1,  to the index stream [Step 0].

              Packit f1137c
              Packit f1137c

              Now we enter the main loop of the algorithm. The next code gets assigned

              Packit f1137c
              to CODE which now makes that value #6. Next we check to see if this value
              Packit f1137c
              is in our code table. At this time, it is not. This means we must find the 
              Packit f1137c
              first index in the value of {CODE-1} and call this K. Thus K = first index of
              Packit f1137c
              {CODE-1} = first index of {#1} = 1. Now we output {CODE-1} + K to the index 
              Packit f1137c
              stream and add this value to our code table. The means we output 1,1 and 
              Packit f1137c
              give this value a code of #6 [Step 1].

              Packit f1137c
              Packit f1137c
              Packit f1137c
              Packit f1137c
              	Step
              Packit f1137c
              	Action
              Packit f1137c
              	Code Stream
              Packit f1137c
              	New Code Table Row
              Packit f1137c
              	Index Stream
              Packit f1137c
              Packit f1137c
              Packit f1137c
              	0
              Packit f1137c
              	Init
              Packit f1137c
              	#4 #1 #6 #6 #2 #9 #9 #7 ...
              Packit f1137c
              	 
              Packit f1137c
              	1
              Packit f1137c
              Packit f1137c
              Packit f1137c
              	1
              Packit f1137c
              	Not Found
              Packit f1137c
              	#4 #1 #6 #6 #2 #9 #9 #7 ...
              Packit f1137c
              	#6 - 1, 1
              Packit f1137c
              	1, 1, 1
              Packit f1137c
              Packit f1137c
              Packit f1137c
              	2
              Packit f1137c
              	Found
              Packit f1137c
              	#4 #1 #6 #6 #2 #9 #9 #7 ...
              Packit f1137c
              	#7 - 1, 1, 1
              Packit f1137c
              	1, 1, 1, 1, 1
              Packit f1137c
              Packit f1137c
              Packit f1137c
              	3
              Packit f1137c
              	Found
              Packit f1137c
              	#4 #1 #6 #6 #2 #9 #9 #7 ...
              Packit f1137c
              	#8 - 1, 1, 2
              Packit f1137c
              	1, 1, 1, 1, 1, 2
              Packit f1137c
              Packit f1137c
              Packit f1137c
              	4
              Packit f1137c
              	Not Found
              Packit f1137c
              	#4 #1 #6 #6 #2 #9 #9 #7 ...
              Packit f1137c
              	#9 - 2, 2
              Packit f1137c
              	1, 1, 1, 1, 1, 2, 2, 2
              Packit f1137c
              Packit f1137c
              Packit f1137c
              	5
              Packit f1137c
              	Found
              Packit f1137c
              	#4 #1 #6 #6 #2 #9 #9 #7 ...
              Packit f1137c
              	#10 - 2, 2, 2
              Packit f1137c
              	1, 1, 1, 1, 1, 2, 2, 2, 2, 2
              Packit f1137c
              Packit f1137c
              Packit f1137c
              	6
              Packit f1137c
              	Found
              Packit f1137c
              	#4 #1 #6 #6 #2 #9 #9 #7 ...
              Packit f1137c
              	#11 - 2, 2, 1
              Packit f1137c
              	1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1
              Packit f1137c
              Packit f1137c
              Packit f1137c
              Packit f1137c

              We start the loop again by reading the next code. CODE now would be

              Packit f1137c
              #6 and this time we do have a record for this code in our code
              Packit f1137c
              table. Thus we dump {#6} to the index stream which would be 1,1.
              Packit f1137c
              Now we take the first index in {#6} and call that K. Here, {#6} has
              Packit f1137c
              two indexes, the first of which is 1; thus K = 1. Before moving
              Packit f1137c
              on, we add {CODE-1}+K to the code table. This #7 is now 1, 1, 1 [Step 2].

              Packit f1137c
              Packit f1137c

              I've included a few more steps so you can see the algorithm in action. While

              Packit f1137c
              the explanation may sound complicated, you can see it's actually quite simple.
              Packit f1137c
              You'll also notice that you end up building the exact same 
              Packit f1137c
              code table
              Packit f1137c
              as the one that was created during compression. This is the reason that
              Packit f1137c
              LZW is so great; we can just share the codes and not the table.

              Packit f1137c
              Packit f1137c

              Saving the Code Stream as Bytes

              Packit f1137c
              Packit f1137c

              I've shown you how to go back and forth between index and code stream, but

              Packit f1137c
              haven't told you what to do with them. The index stream is used to specify the
              Packit f1137c
              color of each of the pixel of your image and really only shows up on screen.
              Packit f1137c
              It is the code stream that is actually saved in the GIF files on your computer 
              Packit f1137c
              or transmitted over the internet. In order to save these code streams, we must
              Packit f1137c
              turn them into bytes. The first thought might be to store each of the codes
              Packit f1137c
              as its own byte; however this would limit the max code to just #255 and 
              Packit f1137c
              result in a lot of wasted bits for the small codes. To solve these problems,
              Packit f1137c
              the GIF file format actually uses flexible code sizes.

              Packit f1137c
              Packit f1137c

              Flexible code sizes allow for further compression by limiting the bits

              Packit f1137c
              needed to save the code stream as bytes. The code size is the number 
              Packit f1137c
              of bits it takes to store the value of the code. When we talk about bits, 
              Packit f1137c
              we're referring to the 1's and 0's that make up a byte. The codes are 
              Packit f1137c
              converted to their binary values to come up with the bits. To specify 
              Packit f1137c
              the code for #4, you would look at this binary equivalent, which is 100, 
              Packit f1137c
              and see that you would need three bits to store this value. The largest code
              Packit f1137c
              value in our sample code stream is #36 (binary: 100100) which would 
              Packit f1137c
              take 6 bits to encode. Note that the number of bits i've just given is 
              Packit f1137c
              the minimum number. You can make the number take up more bits by adding
              Packit f1137c
              zeros to the front.

              Packit f1137c
              Packit f1137c

              GIF image data block layout

              Packit f1137c
              Packit f1137c

              We need a way to know what size each of the codes are. Recall that the

              Packit f1137c
              image data block begins with a single byte value called the 
              Packit f1137c
              LZW minimum code size. The GIF format allows sizes as small
              Packit f1137c
              as 2 bits and as large as 12 bits. This minimum code size value is typically
              Packit f1137c
              the number of bits/pixel of the image. So if you have 32 colors in your image,
              Packit f1137c
              you will need 5 bits/pixel (for numbers 0-31 because 31 in binary is 11111). 
              Packit f1137c
              Thus, this will most likely be one more than the bit value for the size of the 
              Packit f1137c
              color table you are using. (Even if you only have two colors, the minimum
              Packit f1137c
              code size most be at least 2.) Refer to the 
              Packit f1137c
              code table above to remind yourself how that works.

              Packit f1137c
              Packit f1137c

              Here's the funny thing: the value for minimum code size isn't

              Packit f1137c
              actually the smallest code size that's used in the encoding
              Packit f1137c
              process. Because the minimum code size tells you how many bits are
              Packit f1137c
              needed just for the different colors of the image, you still have to
              Packit f1137c
              account for the two special codes that we always add to the code
              Packit f1137c
              table. Therefore the actual smallest code size that will be used is
              Packit f1137c
              one more than the value specified in the "minimum" code size
              Packit f1137c
              byte. I'll call this new value the first code size.

              Packit f1137c
              Packit f1137c

              We now know how many bytes the first code will be. This size will probably

              Packit f1137c
              work for the next few codes as well, but recall that the GIF format
              Packit f1137c
              allows for flexible code sizes. As larger code values get added to your 
              Packit f1137c
              code table, you will soon realize that you need larger code sizes if you 
              Packit f1137c
              were to output those values. When you are encoding the data, you increase
              Packit f1137c
              your code size as soon as your write out the code equal to 
              Packit f1137c
              2^(current code size)-1. If you are decoding from codes to indexes,
              Packit f1137c
              you need to increase your code size as soon as you add the code value that
              Packit f1137c
              is equal to 2^(current code size)-1 to your code table. That is, the next 
              Packit f1137c
              time you grab the next section of bits, you grab one more.

              Packit f1137c
              Packit f1137c

              Note that the largest code size allowed is 12 bits. If you get to this

              Packit f1137c
              limit, the next code you encounter should be the clear code which
              Packit f1137c
              would tell you to reinitialize the code table. You then go back to using 
              Packit f1137c
              the first code size and grow again when necessary.

              Packit f1137c
              Packit f1137c

              Jumping back to our sample image, we see that we have a minimum code

              Packit f1137c
              size value of 2 which means out first code size will be 3 bits long. 
              Packit f1137c
              Out first three codes, #1 #6 and #6, would be coded as 001 110 and 110.
              Packit f1137c
              If you see at Step 6 of the encoding, we added a code of #7 to our code
              Packit f1137c
              table. This is our clue to increase our code size because 7 is equal to
              Packit f1137c
              2^3-1 (where 3 is our current code size). Thus, the next code we 
              Packit f1137c
              write out, #2, will use the new code size of 4 and therefore look
              Packit f1137c
              like 0010. In the decoding process, we again would increase our code
              Packit f1137c
              size when we read the code for #7 and would read the next 4, rather than
              Packit f1137c
              the next 3 bits, to get the next code. In the sample table above this
              Packit f1137c
              occurs in Step 2.

              Packit f1137c
              Packit f1137c

              Finally we must turn all these bit values into bytes. The lowest bit of the

              Packit f1137c
              code bit value gets placed in the lowest available bit of the byte. After
              Packit f1137c
              you've filled up the 8 bits in the byte, you take any left over bits and 
              Packit f1137c
              start a new byte. Take a look at the following illustration to see
              Packit f1137c
              how that works with the codes from our sample image.

              Packit f1137c
              Packit f1137c

              Packit f1137c
              alt="Encoding LZW Codes" style="border: 1px solid black" / WIDTH="500"
              Packit f1137c
              HEIGHT="220">

              Packit f1137c
              Packit f1137c

              You can see in the first byte that was returned (

              Packit f1137c
              class="byte">8C) that the lowest three bits (because that was
              Packit f1137c
              our first code size) contain 110 which is the binary value of 4 so
              Packit f1137c
              that would be the clear code we started with, #4. In the three bits to
              Packit f1137c
              the left, you see 001 which out or first data code of #1. You can also
              Packit f1137c
              see when we switched into code sizes of 4 bits in the second byte
              Packit f1137c
              (2D).

              Packit f1137c
              Packit f1137c

              When you run out of codes but have filled less than 8 bits of the

              Packit f1137c
              byte, you should just fill the remaining bits with zeros. Recall that
              Packit f1137c
              the image data must be broken up onto 
              Packit f1137c
              href="bits_and_bytes.html#image_data_block">data sub-blocks.  Each
              Packit f1137c
              of the data sub-blocks begins with a byte that specifies how many
              Packit f1137c
              bytes of data. The value will be between 1 and 255. After you read
              Packit f1137c
              those bytes, the next byte indicates again how many bytes of data
              Packit f1137c
              follow. You stop when you encounter a subblock that has a lenght of
              Packit f1137c
              zero. That tells you when you've reached the end of the image data. In
              Packit f1137c
              our sample the image the byte just after the LZW code size is 
              Packit f1137c
              class="byte">16 which indicates that 22 bytes of data
              Packit f1137c
              follow. After we reach those, we see the next byte is 
              Packit f1137c
              class="byte">00 which means we are all done.

              Packit f1137c
              Packit f1137c

              Return codes from bytes the basically just the same process in

              Packit f1137c
              reverse.  A sample illustration of the process follows which shows how
              Packit f1137c
              you would extract codes if the first code size were 5 bits.

              Packit f1137c
              Packit f1137c

              Decoding LZW Bytes

              Packit f1137c
              Packit f1137c

              Next: Animation and Transparency

              Packit f1137c
              Packit f1137c

              That is pretty much everything you need to know to read or generate

              Packit f1137c
              a basic image file. One of the reasons the GIF becames such a popular
              Packit f1137c
              format was because it also allowed for "fancier" features. These
              Packit f1137c
              features include animation and transparency. Next we'll look 
              Packit f1137c
              at how those work.

              Packit f1137c
              Packit f1137c

              Continue...

              Packit f1137c
              Packit f1137c
              Packit f1137c
              Packit f1137c
              Back to GIFLIB documentation
              Packit f1137c
              Packit f1137c
              Packit f1137c
              </body>
              Packit f1137c
              Packit f1137c
              </html>