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"
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
27 Inits the range coder state. Must be called before encoding any symbol.
28 It uses a magic number 0xB3 as the first byte outputted.
29 -rangecoder *rc, the range coder to be used.
31 Shoulde be called like that:
32 range_coder_init(&o0_rc_state,file_output);
34 void range_coder_init(rangecoder *rc, FILE *stream)
37 rc->low=0; //define state
39 rc->byte_buffer=0xB3; //magic number
40 rc->help=0; //temp value
46 -rangecoder *rc, the range coder to be used.
47 -unsigned long tot_f, the maximum cumulative frequency
48 -unsigned long lt_f, the cumulative probabilty of the symbol
49 -unsigned long sy_f, the probability of the symbol
51 void range_coder_encode(rangecoder *rc,unsigned long tot_f, unsigned long lt_f,unsigned long sy_f)
53 unsigned long temp, r;
55 range_coder_renormalize(rc); //&rc?
67 Renormalizes the state when coding.
68 -rangecoder *rc, the range coder to be used.
71 void range_coder_renormalize(rangecoder *rc)
73 while(rc->range<=(unsigned long)0x00800000)
75 if(rc->low<(unsigned long)0x7F800000)
77 putc(rc->byte_buffer,rc_file);
78 for(;rc->help;rc->help--)
80 rc->byte_buffer=(unsigned char)(rc->low>>23);
84 if(rc->low&(unsigned long)0x80000000)
86 putc(rc->byte_buffer+1,rc_file);
87 for(;rc->help;rc->help--)
89 rc->byte_buffer=(unsigned char)(rc->low>>23);
95 rc->low=(rc->low<<8)&(unsigned long)(0x7FFFFFFF);
101 Flushes the encoder. Must be called when the coding is done.
102 -rangecoder *rc, the range coder to be used.
104 Shoulde be called like that:
105 range_coder_flush(&o0_rc_state);
107 void range_coder_flush(rangecoder *rc)
111 range_coder_renormalize(rc);
115 putc(rc->byte_buffer+1,rc_file);
116 for(; rc->help; rc->help--)
121 putc(rc->byte_buffer,rc_file);
122 for(; rc->help; rc->help--)
126 putc(tmp & 0xff,rc_file);
127 putc((tmp = rc->low >> (23-8)) & 0xff,rc_file);
132 Inits the range decoder state. Also checks for the magic number, and
133 quits in case it isn't the first, so be careful.
134 -rangecoder *rc, the range coder to be used.
136 void range_decoder_init(rangecoder *rc, FILE *stream)
141 if((_rd_c=getc(rc_file))!=0xB3)
143 printf("\nThis is not range coded data. Magic number not found. Exiting.");
146 rc->byte_buffer=getc(rc_file);
147 rc->low=rc->byte_buffer>>1;
153 Decode a symbol, get its cumulative probability.
155 -rangecoder *rc, the range coder to be used.
156 -unsigned long tot_f, the maximum cumulative probability
158 -unsigned long, cumulative probability of the current symbol
159 Should be called like that:
160 current_cump=range_decoder_decode(&o0_rc_state,o0_tot_f);
162 unsigned long range_decoder_decode(rangecoder *rc, unsigned long tot_f)
166 range_decoder_renormalize(rc);
167 rc->help=rc->range/tot_f;
168 temp=rc->low/rc->help;
177 Updates the state so next symbol can be decoded.
179 -rangecoder *rc, the range coder to be used.
180 -unsigned long tot_f, the maximum cumulative probability
181 -unsigned long lt_f, the cumulative probabilty of the symbol
182 -unsigned long sy_f, the probability of the symbol
185 void range_decoder_update(rangecoder *rc, unsigned long tot_f, unsigned long lt_f,unsigned long sy_f)
192 rc->range=rc->help*sy_f;
199 Renormalizes the state while decoding.
200 -rangecoder *rc, the range coder to be used.
202 void range_decoder_renormalize(rangecoder *rc)
204 while(rc->range<=0x00800000)
206 rc->low=(rc->low<<8)|((rc->byte_buffer<<7)&0xFF);
207 rc->byte_buffer=getc(rc_file);
208 rc->low |= rc->byte_buffer >> (1);