author | pohly <pohly> | 2005-05-05 14:39:33 (UTC) |
---|---|---|
committer | pohly <pohly> | 2005-05-05 14:39:33 (UTC) |
commit | 39fbfd5eb7e45d73d38e8a2ce9437a3d7e1b8e91 (patch) (unidiff) | |
tree | 96e66fdc18dca4d4ab8611133e072f57dea224b9 /noncore/apps/opie-reader/Coder.h | |
parent | 279fc4fd1986074acbadd3a8e86fcf3968a8dd5c (diff) | |
download | opie-39fbfd5eb7e45d73d38e8a2ce9437a3d7e1b8e91.zip opie-39fbfd5eb7e45d73d38e8a2ce9437a3d7e1b8e91.tar.gz opie-39fbfd5eb7e45d73d38e8a2ce9437a3d7e1b8e91.tar.bz2 |
new opie-reader sources with support for ArriereGo, Reb input and flite output plugins
Diffstat (limited to 'noncore/apps/opie-reader/Coder.h') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/apps/opie-reader/Coder.h | 113 |
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 | |||
10 | typedef unsigned int uint; | ||
11 | typedef unsigned char uc; | ||
12 | |||
13 | #define DO(n) for (int _=0; _<n; _++) | ||
14 | #define TOP (1<<24) | ||
15 | #define BOT (1<<16) | ||
16 | |||
17 | |||
18 | class 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 | |||
26 | public: | ||
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 | |||
59 | static struct SUBRANGE { | ||
60 | DWORD LowCount, HighCount, scale; | ||
61 | } SubRange; | ||
62 | enum { TOP=1 << 24, BOT=1 << 15 }; | ||
63 | static DWORD low, code, range; | ||
64 | |||
65 | inline 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 | } | ||
76 | inline void ariEncodeSymbol() | ||
77 | { | ||
78 | low += SubRange.LowCount*(range /= SubRange.scale); | ||
79 | range *= SubRange.HighCount-SubRange.LowCount; | ||
80 | } | ||
81 | inline 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 | } | ||
103 | inline UINT ariGetCurrentCount() { | ||
104 | return (code-low)/(range /= SubRange.scale); | ||
105 | } | ||
106 | inline UINT ariGetCurrentShiftCount(UINT SHIFT) { | ||
107 | return (code-low)/(range >>= SHIFT); | ||
108 | } | ||
109 | inline void ariRemoveSubrange() | ||
110 | { | ||
111 | low += range*SubRange.LowCount; | ||
112 | range *= SubRange.HighCount-SubRange.LowCount; | ||
113 | } | ||