summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-reader/Coder.h
Side-by-side diff
Diffstat (limited to 'noncore/apps/opie-reader/Coder.h') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-reader/Coder.h113
1 files changed, 113 insertions, 0 deletions
diff --git a/noncore/apps/opie-reader/Coder.h b/noncore/apps/opie-reader/Coder.h
new file mode 100644
index 0000000..64587cf
--- a/dev/null
+++ b/noncore/apps/opie-reader/Coder.h
@@ -0,0 +1,113 @@
+#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; _<n; _++)
+#define TOP (1<<24)
+#define BOT (1<<16)
+
+
+class RangeCoder
+{
+ uint low, code, range, passed;
+ FILE *f;
+
+ void OutByte (uc c) { passed++; fputc(c,f); }
+ uc InByte () { passed++; return 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 ((low ^ low+range)<TOP || range<BOT && ((range= -low & BOT-1),1))
+ 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;
+ }
+};
+*****************************************************************************/
+
+static struct SUBRANGE {
+ DWORD LowCount, HighCount, scale;
+} SubRange;
+enum { TOP=1 << 24, BOT=1 << 15 };
+static DWORD low, code, range;
+
+inline void ariInitEncoder()
+{
+ low=0; range=DWORD(-1);
+}
+#define ARI_ENC_NORMALIZE(stream) { \
+ while ((low ^ (low+range)) < TOP || range < BOT && \
+ ((range= -low & (BOT-1)),1)) { \
+ _PPMD_E_PUTC(low >> 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;
+}