2 Copyright (C) Arturo San Emeterio Campos 1999. All rights reserved.
3 Permission is granted to make verbatim copies of this file for private
4 use only. There is ABSOLUTELY NO WARRANTY. Use it at your OWN RISK.
6 This file is: "range.c" (exclusion)
7 Email: arturo@arturocampos.com
8 Web: http://www.arturocampos.com
10 This module contains the routines of both the range coder and decoder.
12 The range coder works internally in 32 bits, and uses bytes as symbols.
13 Also the end of message symbol is used. So z=257.
15 Both input and output use rc_file as the file stream. Of course we can't
16 code and decode at the same time. All the input or output comes from the
17 same file, no matter what range coder structure are we using. The modules
18 here provided don't manage the io except for reading and writing, they
19 don't open nor close the files. The reading and writing is done via
26 Inits the range coder state. Must be called before encoding any symbol.
27 It uses a magic number 0xB3 as the first byte outputted.
28 -rangecoder *rc, the range coder to be used.
30 Shoulde be called like that:
31 range_coder_init(&o0_rc_state,file_output);
33 void range_coder_init(rangecoder *rc, FILE *stream)
36 rc->low=0; //define state
38 rc->byte_buffer=0xB3; //magic number
39 rc->help=0; //temp value
45 -rangecoder *rc, the range coder to be used.
46 -unsigned long tot_f, the maximum cumulative frequency
47 -unsigned long lt_f, the cumulative probabilty of the symbol
48 -unsigned long sy_f, the probability of the symbol
50 void range_coder_encode(rangecoder *rc,unsigned long tot_f, unsigned long lt_f,unsigned long sy_f)
52 unsigned long temp, r;
60 // printf("\nc> %d,%d,%d ",tot_f,lt_f,sy_f);
62 range_coder_renormalize(rc); //&rc?
74 Renormalizes the state when coding.
75 -rangecoder *rc, the range coder to be used.
78 void range_coder_renormalize(rangecoder *rc)
80 while(rc->range<=(unsigned long)0x00800000)
82 if(rc->low<(unsigned long)0x7F800000)
84 putc(rc->byte_buffer,rc_file);
85 for(;rc->help;rc->help--)
87 rc->byte_buffer=(unsigned char)(rc->low>>23);
91 if(rc->low&(unsigned long)0x80000000)
93 putc(rc->byte_buffer+1,rc_file);
94 for(;rc->help;rc->help--)
96 rc->byte_buffer=(unsigned char)(rc->low>>23);
102 rc->low=(rc->low<<8)&(unsigned long)(0x7FFFFFFF);
108 Flushes the encoder. Must be called when the coding is done.
109 -rangecoder *rc, the range coder to be used.
111 Shoulde be called like that:
112 range_coder_flush(&o0_rc_state);
114 void range_coder_flush(rangecoder *rc)
118 range_coder_renormalize(rc);
122 putc(rc->byte_buffer+1,rc_file);
123 for(; rc->help; rc->help--)
128 putc(rc->byte_buffer,rc_file);
129 for(; rc->help; rc->help--)
133 putc(tmp & 0xff,rc_file);
134 putc((tmp = rc->low >> (23-8)) & 0xff,rc_file);
139 Inits the range decoder state. Also checks for the magic number, and
140 quits in case it isn't the first, so be careful.
141 -rangecoder *rc, the range coder to be used.
143 void range_decoder_init(rangecoder *rc, FILE *stream)
148 if((_rd_c=getc(rc_file))!=0xB3)
150 printf("\nThis is not range coded data. Magic number not found. Exiting.");
153 rc->byte_buffer=getc(rc_file);
154 rc->low=rc->byte_buffer>>1;
160 Decode a symbol, get its cumulative probability.
162 -rangecoder *rc, the range coder to be used.
163 -unsigned long tot_f, the maximum cumulative probability
165 -unsigned long, cumulative probability of the current symbol
166 Should be called like that:
167 current_cump=range_decoder_decode(&o0_rc_state,o0_tot_f);
169 unsigned long range_decoder_decode(rangecoder *rc, unsigned long tot_f)
173 range_decoder_renormalize(rc);
174 rc->help=rc->range/tot_f;
175 temp=rc->low/rc->help;
184 Updates the state so next symbol can be decoded.
186 -rangecoder *rc, the range coder to be used.
187 -unsigned long tot_f, the maximum cumulative probability
188 -unsigned long lt_f, the cumulative probabilty of the symbol
189 -unsigned long sy_f, the probability of the symbol
192 void range_decoder_update(rangecoder *rc, unsigned long tot_f, unsigned long lt_f,unsigned long sy_f)
196 // printf("\nd> %d,%d,%d ",tot_f,lt_f,sy_f);
201 rc->range=rc->help*sy_f;
208 Renormalizes the state while decoding.
209 -rangecoder *rc, the range coder to be used.
211 void range_decoder_renormalize(rangecoder *rc)
213 while(rc->range<=0x00800000)
215 rc->low=(rc->low<<8)|((rc->byte_buffer<<7)&0xFF);
216 rc->byte_buffer=getc(rc_file);
217 rc->low |= rc->byte_buffer >> (1);