#include <stdio.h>
typedef unsigned int uint;
typedef unsigned char uc;
#define DO(n) for (int _=0; _<n; _++)
#define TOP (1<<24)
#define BOT (1<<16)
struct RangeCoder {
uint low, code, range, passed;
FILE *f;
void OutByte (uc c) { passed++; /*fputc(c,f);*/ }
uc InByte () { passed++; return 0/*fgetc(f)*/; }
public:
uint GetPassed () { return passed; }
void StartEncode (FILE *F) { f=F; passed=low=0; range= (uint) -1; }
void FinishEncode () { DO(4) OutByte(low>>24), low<<=8; }
void StartDecode (FILE *F) { passed=low=code=0; range= (uint) -1;
f=F; DO(4) code= code<<8 | InByte();
}
void Encode (uint cumFreq, uint freq, uint totFreq) {
// assert(cumFreq+freq<totFreq && freq && totFreq<=BOT);
low += cumFreq * (range/= totFreq);
range*= freq;
while( range<(1<<16) ) { // true
int above = ( low + range) & 0xFFFF; // (0xFFFFFFFF+0x0000FFFF)&0xFFFF = 0xFFFE
int below = (~low) & 0xFFFF; // (~0xFFFFFFFF)&0xFFFF = 0x0000
if( above > below ) { // true
low += range - above; // 0xFFFFFFFF + 0xFFFF-0xFFFE = 0x00000000 !!! OVERFLOW !!!
range = above; // 0xFFFE
} else {
range = below;
}
OutByte( low>>24 );
range <<= 8;
low <<= 8;
}
}
uint GetFreq (uint totFreq) {
uint tmp= (code-low) / (range/= totFreq);
// if (tmp >= totFreq) throw ("Input data corrupt"); // or force it to return
return tmp; // a valid value :)
}
void Decode (uint cumFreq, uint freq, uint totFreq) {
// assert(cumFreq+freq<totFreq && freq && totFreq<=BOT);
low += cumFreq*range;
range*= freq;
while ((low ^ low+range)<TOP || range<BOT && ((range= -low & BOT-1),1))
code= code<<8 | InByte(), range<<=8, low<<=8;
}
} rc;
int main( void ) {
rc.StartEncode(0);
for( int i=0; i<999999; i++ ) rc.Encode( 254,1,255 );
printf( "output bytes = %i\n", rc.passed );
}