#include "CSource.h" /**************************************************************************** * 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> 24,stream); \ range <<= 8; low <<= 8; \ } \ } inline void ariEncodeSymbol() { low += SubRange.LowCount*(range /= SubRange.scale); range *= SubRange.HighCount-SubRange.LowCount; } inline void ariShiftEncodeSymbol(UINT SHIFT) { low += SubRange.LowCount*(range >>= SHIFT); range *= SubRange.HighCount-SubRange.LowCount; } #define ARI_FLUSH_ENCODER(stream) { \ for (UINT i=0;i < 4;i++) { \ _PPMD_E_PUTC(low >> 24,stream); low <<= 8; \ } \ } #define ARI_INIT_DECODER(stream) { \ low=code=0; range=DWORD(-1); \ for (UINT i=0;i < 4;i++) \ code=(code << 8) | _PPMD_D_GETC(stream); \ } #define ARI_DEC_NORMALIZE(stream) { \ while ((low ^ (low+range)) < TOP || range < BOT && \ ((range= -low & (BOT-1)),1)) { \ code=(code << 8) | _PPMD_D_GETC(stream); \ range <<= 8; low <<= 8; \ } \ } inline UINT ariGetCurrentCount() { return (code-low)/(range /= SubRange.scale); } inline UINT ariGetCurrentShiftCount(UINT SHIFT) { return (code-low)/(range >>= SHIFT); } inline void ariRemoveSubrange() { low += range*SubRange.LowCount; range *= SubRange.HighCount-SubRange.LowCount; }