Context algorithm
Semi-predictive context algorithm implementation
 All Data Structures Files Functions Variables Typedefs Macros Pages
coder.c
Go to the documentation of this file.
1 /*
2  * Listing 2 -- coder.c
3  *
4  * This file contains the code needed to accomplish arithmetic
5  * coding of a symbol. All the routines in this module need
6  * to know in order to accomplish coding is what the probabilities
7  * and scales of the symbol counts are. This information is
8  * generally passed in a SYMBOL structure.
9  *
10  * This code was first published by Ian H. Witten, Radford M. Neal,
11  * and John G. Cleary in "Communications of the ACM" in June 1987,
12  * and has been modified slightly for this article. The code
13  * is published here with permission.
14  */
15 
16 #include <stdio.h>
17 #include "coder.h"
18 #include "bitio.h"
19 
20 /*
21  * These four variables define the current state of the arithmetic
22  * coder/decoder. They are assumed to be 16 bits long. Note that
23  * by declaring them as short ints, they will actually be 16 bits
24  * on most 80X86 and 680X0 machines, as well as VAXen.
25  */
26 static unsigned short int code; /* The present input code value */
27 static unsigned short int low; /* Start of the current code range */
28 static unsigned short int high; /* End of the current code range */
29 long underflow_bits; /* Number of underflow bits pending */
30 
31 /*
32  * This routine must be called to initialize the encoding process.
33  * The high register is initialized to all 1s, and it is assumed that
34  * it has an infinite string of 1s to be shifted into the lower bit
35  * positions when needed.
36  */
38 {
39  low = 0;
40  high = 0xffff;
41  underflow_bits = 0;
42 }
43 
44 /*
45  * This routine is called to encode a symbol. The symbol is passed
46  * in the SYMBOL structure as a low count, a high count, and a range,
47  * instead of the more conventional probability ranges. The encoding
48  * process takes two steps. First, the values of high and low are
49  * updated to take into account the range restriction created by the
50  * new symbol. Then, as many bits as possible are shifted out to
51  * the output stream. Finally, high and low are stable again and
52  * the routine returns.
53  */
54 void encode_symbol( FILE *stream, SYMBOL *s )
55 {
56  long range;
57 /*
58  * These three lines rescale high and low for the new symbol.
59  */
60  range = (long) ( high-low ) + 1;
61  high = low + (unsigned short int )
62  (( range * s->high_count ) / s->scale - 1 );
63  low = low + (unsigned short int )
64  (( range * s->low_count ) / s->scale );
65 /*
66  * This loop turns out new bits until high and low are far enough
67  * apart to have stabilized.
68  */
69  for ( ; ; )
70  {
71 /*
72  * If this test passes, it means that the MSDigits match, and can
73  * be sent to the output stream.
74  */
75  if ( ( high & 0x8000 ) == ( low & 0x8000 ) )
76  {
77  output_bit( stream, high & 0x8000 );
78  while ( underflow_bits > 0 )
79  {
80  output_bit( stream, ~high & 0x8000 );
82  }
83  }
84 /*
85  * If this test passes, the numbers are in danger of underflow, because
86  * the MSDigits don't match, and the 2nd digits are just one apart.
87  */
88  else if ( ( low & 0x4000 ) && !( high & 0x4000 ))
89  {
90  underflow_bits += 1;
91  low &= 0x3fff;
92  high |= 0x4000;
93  }
94  else {
95  return ;
96  }
97  low <<= 1;
98  high <<= 1;
99  high |= 1;
100  }
101 }
102 
103 /*
104  * At the end of the encoding process, there are still significant
105  * bits left in the high and low registers. We output two bits,
106  * plus as many underflow bits as are necessary.
107  */
108 void flush_arithmetic_encoder( FILE *stream )
109 {
110  output_bit( stream, low & 0x4000 );
111  underflow_bits++;
112  while ( underflow_bits-- > 0 )
113  output_bit( stream, ~low & 0x4000 );
114 }
115 
116 /*
117  * When decoding, this routine is called to figure out which symbol
118  * is presently waiting to be decoded. This routine expects to get
119  * the current model scale in the s->scale parameter, and it returns
120  * a count that corresponds to the present floating point code:
121  *
122  * code = count / s->scale
123  */
124 short int get_current_count( SYMBOL *s )
125 {
126  long range;
127  short int count;
128 
129  range = (long) ( high - low ) + 1;
130  count = (short int)
131  ((((long) ( code - low ) + 1 ) * s->scale-1 ) / range );
132  return( count );
133 }
134 
135 /*
136  * This routine is called to initialize the state of the arithmetic
137  * decoder. This involves initializing the high and low registers
138  * to their conventional starting values, plus reading the first
139  * 16 bits from the input stream into the code value.
140  */
141 void initialize_arithmetic_decoder( FILE *stream )
142 {
143  int i;
144 
145  code = 0;
146  for ( i = 0 ; i < 16 ; i++ )
147  {
148  code <<= 1;
149  code += input_bit( stream );
150  }
151  low = 0;
152  high = 0xffff;
153 }
154 
155 /*
156  * Just figuring out what the present symbol is doesn't remove
157  * it from the input bit stream. After the character has been
158  * decoded, this routine has to be called to remove it from the
159  * input stream.
160  */
161 void remove_symbol_from_stream( FILE *stream, SYMBOL *s )
162 {
163  long range;
164 
165 /*
166  * First, the range is expanded to account for the symbol removal.
167  */
168  range = (long)( high - low ) + 1;
169  high = low + (unsigned short int)
170  (( range * s->high_count ) / s->scale - 1 );
171  low = low + (unsigned short int)
172  (( range * s->low_count ) / s->scale );
173 /*
174  * Next, any possible bits are shipped out.
175  */
176  for ( ; ; )
177  {
178 /*
179  * If the MSDigits match, the bits will be shifted out.
180  */
181  if ( ( high & 0x8000 ) == ( low & 0x8000 ) )
182  {
183  }
184 /*
185  * Else, if underflow is threatining, shift out the 2nd MSDigit.
186  */
187  else if ((low & 0x4000) == 0x4000 && (high & 0x4000) == 0 )
188  {
189  code ^= 0x4000;
190  low &= 0x3fff;
191  high |= 0x4000;
192  }
193 /*
194  * Otherwise, nothing can be shifted out, so I return.
195  */
196  else
197  return;
198  low <<= 1;
199  high <<= 1;
200  high |= 1;
201  code <<= 1;
202  code += input_bit( stream );
203  }
204 }
205 
206 
void initialize_arithmetic_decoder(FILE *stream)
Definition: coder.c:141
unsigned short int scale
Definition: coder.h:24
void encode_symbol(FILE *stream, SYMBOL *s)
Definition: coder.c:54
Definition: coder.h:21
void initialize_arithmetic_encoder()
Definition: coder.c:37
long underflow_bits
Definition: coder.c:29
static unsigned short int code
Definition: coder.c:26
static unsigned short int low
Definition: coder.c:27
void output_bit(FILE *stream, int bit)
Definition: bitio.c:62
unsigned short int low_count
Definition: coder.h:22
void flush_arithmetic_encoder(FILE *stream)
Definition: coder.c:108
static unsigned short int high
Definition: coder.c:28
short int input_bit(FILE *stream)
Definition: bitio.c:112
unsigned short int high_count
Definition: coder.h:23
void remove_symbol_from_stream(FILE *stream, SYMBOL *s)
Definition: coder.c:161
short int get_current_count(SYMBOL *s)
Definition: coder.c:124