summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-reader/arith_d.cpp
Unidiff
Diffstat (limited to 'noncore/apps/opie-reader/arith_d.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-reader/arith_d.cpp94
1 files changed, 94 insertions, 0 deletions
diff --git a/noncore/apps/opie-reader/arith_d.cpp b/noncore/apps/opie-reader/arith_d.cpp
new file mode 100644
index 0000000..c43d697
--- a/dev/null
+++ b/noncore/apps/opie-reader/arith_d.cpp
@@ -0,0 +1,94 @@
1/* décodage arithmétique
2 * optimisé pour une arithmétique 16 bits
3 */
4#include <stdlib.h>
5#include "arith.h"
6
7
8/*
9 * Initialisation du décodeur.
10 * bufsize doit être multiple de 2 et supérieur à 4
11 */
12
13void ArithClass::Arith_DecodeInit(PPM_ReadBuf* readbuf,UCHAR *buf,UINT bufsize) {
14
15 /* gestion buffer */
16
17 ainbuf=buf;
18 ainbufsize=bufsize;
19 areadbuf=readbuf;
20 aendinbuf=ainbuf+ainbufsize;
21 areadbuf->readbuf(ainbuf,ainbufsize);
22 apinbuf=ainbuf;
23
24 /* intervalle et position dans l'intervalle */
25 alow=0;
26 ahigh=0xFFFF;
27 avalue=(*apinbuf++)<<8;
28 avalue|=(*apinbuf++);
29
30 /* remplissage du buffer 16 bits */
31
32 abitbuf=(*apinbuf++)<<8;
33 abitbuf|=(*apinbuf++);
34 abitcnt=16;
35}
36
37 #define DIV16(a,b) ( (UINT)(a)/(UINT)(b) )
38 #define MUL16(a,b) ( (UINT)(a)*(UINT)(b) )
39
40/*
41 * Décodage: première étape
42 */
43
44UINT ArithClass::Arith_DecodeVal(UINT asize) {
45 USHORT range,c;
46
47 range=ahigh-alow+1;
48 c=avalue-alow+1;
49 if (range!=0) {
50 if (c==0) return DIV16(((UINT)asize<<16)-1,range);
51 else return DIV16(MUL16(c,asize)-1,range);
52 } else {
53 if (c==0) return (asize-1);
54 else return (MUL16(c,asize)-1)>>16;
55 }
56}
57
58/*
59 * Décodage: deuxième étape
60 */
61
62void ArithClass::Arith_Decode(UINT amin,UINT amax,UINT asize) {
63 USHORT range;
64
65 range = ahigh - alow;
66 if (amax!=asize) ahigh=alow+DIV16(MUL16(range,amax)+amax,asize)-1;
67 if (amin!=0) alow+=DIV16(MUL16(range,amin)+amin,asize);
68 for ( ; ; ) {
69 if ( alow>=0x4000 && ahigh<0xC000 ) {
70 avalue -= 0x4000; alow -= 0x4000; ahigh -= 0x4000;
71 } else if ( ahigh>=0x8000 && alow<0x8000 ) break;
72
73 alow+=alow;
74 ahigh+=ahigh+1;
75 avalue=(avalue<<1)|( (abitbuf&0x8000)!=0 );
76 abitbuf<<=1;
77 if ( (--abitcnt)==0 ) {
78 abitbuf=(*apinbuf++)<<8;
79 abitbuf|=(*apinbuf++);
80 abitcnt=16;
81 if (apinbuf>=aendinbuf) {
82 areadbuf->readbuf(ainbuf,ainbufsize);
83 apinbuf=ainbuf;
84 }
85 }
86 }
87}
88
89/*
90 * fin du décodage: rien à faire
91 */
92
93void ArithClass::Arith_DecodeEnd(void) {
94}