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