/**************************************************************************** * This file is part of PPMd project * * Contents: 'Carryless rangecoder' by Dmitry Subbotin * * Comments: this implementation is claimed to be a public domain * ****************************************************************************/ /********************** Original text ************************************* //////// Carryless rangecoder (c) 1999 by Dmitry Subbotin //////// typedef unsigned int uint; typedef unsigned char uc; #define DO(n) for (int _=0; _>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>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>= SHIFT); } inline void Ari::RemoveSubrange() { low += range*SubRange.LowCount; range *= SubRange.HighCount-SubRange.LowCount; } inline void Ari::EncoderInit() { low=0; range=DWORD(-1); } inline void Ari::EncoderNormalize(PPMD_Out *stream) { while ((low ^ (low+range)) < TOP || range < BOT && ((range= -low & (BOT-1)),1)) { _PPMD_E_PUTC((unsigned char)(low >> 24),stream); range <<= 8; low <<= 8; } } inline void Ari::EncodeSymbol() { low += SubRange.LowCount*(range /= SubRange.scale); range *= SubRange.HighCount-SubRange.LowCount; } inline void Ari::ShiftEncodeSymbol(UINT SHIFT) { low += SubRange.LowCount*(range >>= SHIFT); range *= SubRange.HighCount-SubRange.LowCount; } inline void Ari::EncoderFlush(PPMD_Out *stream) { for (UINT i=0;i < 4;i++) { _PPMD_E_PUTC(low >> 24,stream); low <<= 8; } } inline void Ari::DecoderInit(PPMD_In *stream) { low=code=0; range=DWORD(-1); for (UINT i=0;i < 4;i++) code=(code << 8) | _PPMD_D_GETC(stream); } inline void Ari::DecoderNormalize(PPMD_In *stream) { while ((low ^ (low+range)) < TOP || range < BOT && ((range= -low & (BOT-1)),1)) { code=(code << 8) | _PPMD_D_GETC(stream); range <<= 8; low <<= 8; } }