00001
00002
00003
00004 #include <stdlib.h>
00005 #include "arith.h"
00006
00007
00008
00009
00010
00011
00012
00013 void ArithClass::Arith_DecodeInit(PPM_ReadBuf* readbuf,UCHAR *buf,UINT bufsize) {
00014
00015
00016
00017 ainbuf=buf;
00018 ainbufsize=bufsize;
00019 areadbuf=readbuf;
00020 aendinbuf=ainbuf+ainbufsize;
00021 areadbuf->readbuf(ainbuf,ainbufsize);
00022 apinbuf=ainbuf;
00023
00024
00025 alow=0;
00026 ahigh=0xFFFF;
00027 avalue=(*apinbuf++)<<8;
00028 avalue|=(*apinbuf++);
00029
00030
00031
00032 abitbuf=(*apinbuf++)<<8;
00033 abitbuf|=(*apinbuf++);
00034 abitcnt=16;
00035 }
00036
00037 #define DIV16(a,b) ( (UINT)(a)/(UINT)(b) )
00038 #define MUL16(a,b) ( (UINT)(a)*(UINT)(b) )
00039
00040
00041
00042
00043
00044 UINT ArithClass::Arith_DecodeVal(UINT asize) {
00045 USHORT range,c;
00046
00047 range=ahigh-alow+1;
00048 c=avalue-alow+1;
00049 if (range!=0) {
00050 if (c==0) return DIV16(((UINT)asize<<16)-1,range);
00051 else return DIV16(MUL16(c,asize)-1,range);
00052 } else {
00053 if (c==0) return (asize-1);
00054 else return (MUL16(c,asize)-1)>>16;
00055 }
00056 }
00057
00058
00059
00060
00061
00062 void ArithClass::Arith_Decode(UINT amin,UINT amax,UINT asize) {
00063 USHORT range;
00064
00065 range = ahigh - alow;
00066 if (amax!=asize) ahigh=alow+DIV16(MUL16(range,amax)+amax,asize)-1;
00067 if (amin!=0) alow+=DIV16(MUL16(range,amin)+amin,asize);
00068 for ( ; ; ) {
00069 if ( alow>=0x4000 && ahigh<0xC000 ) {
00070 avalue -= 0x4000; alow -= 0x4000; ahigh -= 0x4000;
00071 } else if ( ahigh>=0x8000 && alow<0x8000 ) break;
00072
00073 alow+=alow;
00074 ahigh+=ahigh+1;
00075 avalue=(avalue<<1)|( (abitbuf&0x8000)!=0 );
00076 abitbuf<<=1;
00077 if ( (--abitcnt)==0 ) {
00078 abitbuf=(*apinbuf++)<<8;
00079 abitbuf|=(*apinbuf++);
00080 abitcnt=16;
00081 if (apinbuf>=aendinbuf) {
00082 areadbuf->readbuf(ainbuf,ainbufsize);
00083 apinbuf=ainbuf;
00084 }
00085 }
00086 }
00087 }
00088
00089
00090
00091
00092
00093 void ArithClass::Arith_DecodeEnd(void) {
00094 }