/*
- Copyright (C) Arturo San Emeterio Campos 1999. All rights reserved.
- Permission is granted to make verbatim copies of this file for private
- use only. There is ABSOLUTELY NO WARRANTY. Use it at your OWN RISK.
+ Copyright (C) Arturo San Emeterio Campos 1999. All rights reserved.
+ Permission is granted to make verbatim copies of this file for private
+ use only. There is ABSOLUTELY NO WARRANTY. Use it at your OWN RISK.
- This file is: "range.c"
- Email: arturo@arturocampos.com
- Web: http://www.arturocampos.com
+ This file is: "range.c"
+Email: arturo@arturocampos.com
+Web: http://www.arturocampos.com
- This module contains the routines of both the range coder and decoder.
+This module contains the routines of both the range coder and decoder.
- The range coder works internally in 32 bits, and uses bytes as symbols.
- Also the end of message symbol is used. So z=257.
+The range coder works internally in 32 bits, and uses bytes as symbols.
+Also the end of message symbol is used. So z=257.
- Both input and output use rc_file as the file stream. Of course we can't
- code and decode at the same time. All the input or output comes from the
- same file, no matter what range coder structure are we using. The modules
- here provided don't manage the io except for reading and writing, they
- don't open nor close the files. The reading and writing is done via
- putc and getc.
+Both input and output use rc_file as the file stream. Of course we can't
+code and decode at the same time. All the input or output comes from the
+same file, no matter what range coder structure are we using. The modules
+here provided don't manage the io except for reading and writing, they
+don't open nor close the files. The reading and writing is done via
+putc and getc.
*/
#include "range.h"
#include <stdlib.h>
/*
- Inits the range coder state. Must be called before encoding any symbol.
- It uses a magic number 0xB3 as the first byte outputted.
- -rangecoder *rc, the range coder to be used.
+ Inits the range coder state. Must be called before encoding any symbol.
+ It uses a magic number 0xB3 as the first byte outputted.
+ -rangecoder *rc, the range coder to be used.
- Shoulde be called like that:
- range_coder_init(&o0_rc_state,file_output);
-*/
+ Shoulde be called like that:
+ range_coder_init(&o0_rc_state,file_output);
+ */
void range_coder_init(rangecoder *rc, FILE *stream)
{
- rc_file=stream;
- rc->low=0; //define state
- rc->range=0x80000000;
- rc->byte_buffer=0xB3; //magic number
- rc->help=0; //temp value
+ rc_file=stream;
+ rc->low=0; //define state
+ rc->range=0x80000000;
+ rc->byte_buffer=0xB3; //magic number
+ rc->help=0; //temp value
}
/*
- Encodes a symbol.
- -rangecoder *rc, the range coder to be used.
- -unsigned long tot_f, the maximum cumulative frequency
- -unsigned long lt_f, the cumulative probabilty of the symbol
- -unsigned long sy_f, the probability of the symbol
-*/
+ Encodes a symbol.
+ -rangecoder *rc, the range coder to be used.
+ -unsigned long tot_f, the maximum cumulative frequency
+ -unsigned long lt_f, the cumulative probabilty of the symbol
+ -unsigned long sy_f, the probability of the symbol
+ */
void range_coder_encode(rangecoder *rc,unsigned long tot_f, unsigned long lt_f,unsigned long sy_f)
{
- unsigned long temp, r;
+ unsigned long temp, r;
- range_coder_renormalize(rc); //&rc?
+ range_coder_renormalize(rc); //&rc?
- r=rc->range/tot_f;
- temp=r*lt_f;
- if(lt_f+sy_f<tot_f)
- rc->range=r*sy_f;
- else
- rc->range-=temp;
- rc->low+=temp;
+ r=rc->range/tot_f;
+ temp=r*lt_f;
+ if(lt_f+sy_f<tot_f)
+ rc->range=r*sy_f;
+ else
+ rc->range-=temp;
+ rc->low+=temp;
}
/*
- Renormalizes the state when coding.
- -rangecoder *rc, the range coder to be used.
-*/
+ Renormalizes the state when coding.
+ -rangecoder *rc, the range coder to be used.
+ */
void range_coder_renormalize(rangecoder *rc)
{
- while(rc->range<=(unsigned long)0x00800000)
- {
- if(rc->low<(unsigned long)0x7F800000)
- {
- putc(rc->byte_buffer,rc_file);
- for(;rc->help;rc->help--)
- putc(0xFF,rc_file);
- rc->byte_buffer=(unsigned char)(rc->low>>23);
- }
- else
- {
- if(rc->low&(unsigned long)0x80000000)
- {
- putc(rc->byte_buffer+1,rc_file);
- for(;rc->help;rc->help--)
- putc(0x00,rc_file);
- rc->byte_buffer=(unsigned char)(rc->low>>23);
- }
- else
- rc->help++;
- }
- rc->range<<=8;
- rc->low=(rc->low<<8)&(unsigned long)(0x7FFFFFFF);
- }
+ while(rc->range<=(unsigned long)0x00800000)
+ {
+ if(rc->low<(unsigned long)0x7F800000)
+ {
+ putc(rc->byte_buffer,rc_file);
+ for(;rc->help;rc->help--)
+ putc(0xFF,rc_file);
+ rc->byte_buffer=(unsigned char)(rc->low>>23);
+ }
+ else
+ {
+ if(rc->low&(unsigned long)0x80000000)
+ {
+ putc(rc->byte_buffer+1,rc_file);
+ for(;rc->help;rc->help--)
+ putc(0x00,rc_file);
+ rc->byte_buffer=(unsigned char)(rc->low>>23);
+ }
+ else
+ rc->help++;
+ }
+ rc->range<<=8;
+ rc->low=(rc->low<<8)&(unsigned long)(0x7FFFFFFF);
+ }
}
/*
- Flushes the encoder. Must be called when the coding is done.
- -rangecoder *rc, the range coder to be used.
+ Flushes the encoder. Must be called when the coding is done.
+ -rangecoder *rc, the range coder to be used.
- Shoulde be called like that:
- range_coder_flush(&o0_rc_state);
-*/
+ Shoulde be called like that:
+ range_coder_flush(&o0_rc_state);
+ */
void range_coder_flush(rangecoder *rc)
{
- unsigned long tmp;
-
- range_coder_renormalize(rc);
- tmp = rc->low >> 23;
- if (tmp > 0xff)
- {
- putc(rc->byte_buffer+1,rc_file);
- for(; rc->help; rc->help--)
- putc(0,rc_file);
- }
- else
- {
- putc(rc->byte_buffer,rc_file);
- for(; rc->help; rc->help--)
- putc(0xff,rc_file);
- }
-
- putc(tmp & 0xff,rc_file);
- putc((tmp = rc->low >> (23-8)) & 0xff,rc_file);
+ unsigned long tmp;
+
+ range_coder_renormalize(rc);
+ tmp = rc->low >> 23;
+ if (tmp > 0xff)
+ {
+ putc(rc->byte_buffer+1,rc_file);
+ for(; rc->help; rc->help--)
+ putc(0,rc_file);
+ }
+ else
+ {
+ putc(rc->byte_buffer,rc_file);
+ for(; rc->help; rc->help--)
+ putc(0xff,rc_file);
+ }
+
+ putc(tmp & 0xff,rc_file);
+ putc((tmp = rc->low >> (23-8)) & 0xff,rc_file);
}
/*
- Inits the range decoder state. Also checks for the magic number, and
- quits in case it isn't the first, so be careful.
- -rangecoder *rc, the range coder to be used.
-*/
+ Inits the range decoder state. Also checks for the magic number, and
+ quits in case it isn't the first, so be careful.
+ -rangecoder *rc, the range coder to be used.
+ */
void range_decoder_init(rangecoder *rc, FILE *stream)
{
- unsigned int _rd_c;
-
- rc_file=stream;
- if((_rd_c=getc(rc_file))!=0xB3)
- {
- printf("\nThis is not range coded data. Magic number not found. Exiting.");
- exit(1);
- }
- rc->byte_buffer=getc(rc_file);
- rc->low=rc->byte_buffer>>1;
- rc->range=0x80;
+ unsigned int _rd_c;
+
+ rc_file=stream;
+ if((_rd_c=getc(rc_file))!=0xB3)
+ {
+ printf("\nThis is not range coded data. Magic number not found. Exiting.");
+ exit(1);
+ }
+ rc->byte_buffer=getc(rc_file);
+ rc->low=rc->byte_buffer>>1;
+ rc->range=0x80;
}
/*
- Decode a symbol, get its cumulative probability.
- Input:
- -rangecoder *rc, the range coder to be used.
- -unsigned long tot_f, the maximum cumulative probability
- Output:
- -unsigned long, cumulative probability of the current symbol
- Should be called like that:
- current_cump=range_decoder_decode(&o0_rc_state,o0_tot_f);
+ Decode a symbol, get its cumulative probability.
+Input:
+-rangecoder *rc, the range coder to be used.
+-unsigned long tot_f, the maximum cumulative probability
+Output:
+-unsigned long, cumulative probability of the current symbol
+Should be called like that:
+current_cump=range_decoder_decode(&o0_rc_state,o0_tot_f);
*/
unsigned long range_decoder_decode(rangecoder *rc, unsigned long tot_f)
{
- unsigned long temp;
-
- range_decoder_renormalize(rc);
- rc->help=rc->range/tot_f;
- temp=rc->low/rc->help;
- if(temp>=tot_f)
- return tot_f-1;
- else
- return temp;
+ unsigned long temp;
+
+ range_decoder_renormalize(rc);
+ rc->help=rc->range/tot_f;
+ temp=rc->low/rc->help;
+ if(temp>=tot_f)
+ return tot_f-1;
+ else
+ return temp;
}
/*
- Updates the state so next symbol can be decoded.
- Input:
- -rangecoder *rc, the range coder to be used.
- -unsigned long tot_f, the maximum cumulative probability
- -unsigned long lt_f, the cumulative probabilty of the symbol
- -unsigned long sy_f, the probability of the symbol
+ Updates the state so next symbol can be decoded.
+Input:
+-rangecoder *rc, the range coder to be used.
+-unsigned long tot_f, the maximum cumulative probability
+-unsigned long lt_f, the cumulative probabilty of the symbol
+-unsigned long sy_f, the probability of the symbol
*/
void range_decoder_update(rangecoder *rc, unsigned long tot_f, unsigned long lt_f,unsigned long sy_f)
{
- unsigned long temp;
-
- temp=rc->help*lt_f;
- rc->low-=temp;
- if(lt_f+sy_f<tot_f)
- rc->range=rc->help*sy_f;
- else
- rc->range-=temp;
+ unsigned long temp;
+
+ temp=rc->help*lt_f;
+ rc->low-=temp;
+ if(lt_f+sy_f<tot_f)
+ rc->range=rc->help*sy_f;
+ else
+ rc->range-=temp;
}
/*
- Renormalizes the state while decoding.
- -rangecoder *rc, the range coder to be used.
-*/
+ Renormalizes the state while decoding.
+ -rangecoder *rc, the range coder to be used.
+ */
void range_decoder_renormalize(rangecoder *rc)
{
- while(rc->range<=0x00800000)
- {
- rc->low=(rc->low<<8)|((rc->byte_buffer<<7)&0xFF);
- rc->byte_buffer=getc(rc_file);
- rc->low |= rc->byte_buffer >> (1);
- rc->range<<=8;
- }
+ while(rc->range<=0x00800000)
+ {
+ rc->low=(rc->low<<8)|((rc->byte_buffer<<7)&0xFF);
+ rc->byte_buffer=getc(rc_file);
+ rc->low |= rc->byte_buffer >> (1);
+ rc->range<<=8;
+ }
}