summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-reader/Coder.h
Unidiff
Diffstat (limited to 'noncore/apps/opie-reader/Coder.h') (more/less context) (show 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 @@
1#include "CSource.h"
2/****************************************************************************
3 * This file is part of PPMd project *
4 * Contents: 'Carryless rangecoder' by Dmitry Subbotin *
5 * Comments: this implementation is claimed to be a public domain *
6 ****************************************************************************/
7/********************** Original text *************************************
8//////// Carryless rangecoder (c) 1999 by Dmitry Subbotin ////////
9
10typedef unsigned int uint;
11typedef unsigned char uc;
12
13#define DO(n) for (int _=0; _<n; _++)
14#define TOP (1<<24)
15#define BOT (1<<16)
16
17
18class RangeCoder
19{
20 uint low, code, range, passed;
21 FILE *f;
22
23 void OutByte (uc c) { passed++; fputc(c,f); }
24 uc InByte () { passed++; return fgetc(f); }
25
26public:
27
28 uint GetPassed () { return passed; }
29 void StartEncode (FILE *F) { f=F; passed=low=0; range= (uint) -1; }
30 void FinishEncode () { DO(4) OutByte(low>>24), low<<=8; }
31 void StartDecode (FILE *F) { passed=low=code=0; range= (uint) -1;
32 f=F; DO(4) code= code<<8 | InByte();
33 }
34
35 void Encode (uint cumFreq, uint freq, uint totFreq) {
36 assert(cumFreq+freq<totFreq && freq && totFreq<=BOT);
37 low += cumFreq * (range/= totFreq);
38 range*= freq;
39 while ((low ^ low+range)<TOP || range<BOT && ((range= -low & BOT-1),1))
40 OutByte(low>>24), range<<=8, low<<=8;
41 }
42
43 uint GetFreq (uint totFreq) {
44 uint tmp= (code-low) / (range/= totFreq);
45 if (tmp >= totFreq) throw ("Input data corrupt"); // or force it to return
46 return tmp; // a valid value :)
47 }
48
49 void Decode (uint cumFreq, uint freq, uint totFreq) {
50 assert(cumFreq+freq<totFreq && freq && totFreq<=BOT);
51 low += cumFreq*range;
52 range*= freq;
53 while ((low ^ low+range)<TOP || range<BOT && ((range= -low & BOT-1),1))
54 code= code<<8 | InByte(), range<<=8, low<<=8;
55 }
56};
57*****************************************************************************/
58
59static struct SUBRANGE {
60 DWORD LowCount, HighCount, scale;
61} SubRange;
62enum { TOP=1 << 24, BOT=1 << 15 };
63static DWORD low, code, range;
64
65inline void ariInitEncoder()
66{
67 low=0; range=DWORD(-1);
68}
69#define ARI_ENC_NORMALIZE(stream) { \
70 while ((low ^ (low+range)) < TOP || range < BOT && \
71 ((range= -low & (BOT-1)),1)) { \
72 _PPMD_E_PUTC(low >> 24,stream); \
73 range <<= 8; low <<= 8; \
74 } \
75}
76inline void ariEncodeSymbol()
77{
78 low += SubRange.LowCount*(range /= SubRange.scale);
79 range *= SubRange.HighCount-SubRange.LowCount;
80}
81inline void ariShiftEncodeSymbol(UINT SHIFT)
82{
83 low += SubRange.LowCount*(range >>= SHIFT);
84 range *= SubRange.HighCount-SubRange.LowCount;
85}
86#define ARI_FLUSH_ENCODER(stream) { \
87 for (UINT i=0;i < 4;i++) { \
88 _PPMD_E_PUTC(low >> 24,stream); low <<= 8; \
89 } \
90}
91#define ARI_INIT_DECODER(stream) { \
92 low=code=0; range=DWORD(-1); \
93 for (UINT i=0;i < 4;i++) \
94 code=(code << 8) | _PPMD_D_GETC(stream); \
95}
96#define ARI_DEC_NORMALIZE(stream) { \
97 while ((low ^ (low+range)) < TOP || range < BOT && \
98 ((range= -low & (BOT-1)),1)) { \
99 code=(code << 8) | _PPMD_D_GETC(stream); \
100 range <<= 8; low <<= 8; \
101 } \
102}
103inline UINT ariGetCurrentCount() {
104 return (code-low)/(range /= SubRange.scale);
105}
106inline UINT ariGetCurrentShiftCount(UINT SHIFT) {
107 return (code-low)/(range >>= SHIFT);
108}
109inline void ariRemoveSubrange()
110{
111 low += range*SubRange.LowCount;
112 range *= SubRange.HighCount-SubRange.LowCount;
113}