#include "MatComp.h" #include #include #include #include #define MC_MASK_X ((1<<(MC_BITS_X))-1) #define MC_MASK_Y ((1<<(MC_BITS_Y))-1) #define MC_MASK_Z ((1<<(MC_BITS_Z))-1) #define MC_MASK_VECT ((1<<(MC_BITS_VECT))-1) #define MC_N_VECT (1<<(MC_BITS_VECT)) #define MC_POS_X (0) #define MC_SHIFT_X (0) #define MC_POS_Y ((((MC_BITS_X))/8)) #define MC_SHIFT_Y ((((MC_BITS_X)%8))) #define MC_POS_Z ((((MC_BITS_X+MC_BITS_Y))/8)) #define MC_SHIFT_Z ((((MC_BITS_X+MC_BITS_Y)%8))) #define MC_POS_V1 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z))/8)) #define MC_SHIFT_V1 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z)%8))) #define MC_POS_V2 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT))/8)) #define MC_SHIFT_V2 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT)%8))) #define MC_POS_V3 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*2))/8)) #define MC_SHIFT_V3 ((((MC_BITS_X+MC_BITS_Y+MC_BITS_Z+MC_BITS_VECT*2)%8))) #define MAXBIT 30 #define MAXDIM 6 void sobseq(int n, int *x) { int j,k,l; unsigned int i,im,ipp; static unsigned int in,ix[MAXDIM+1],*iu[MAXBIT+1]; static unsigned int mdeg[MAXDIM+1]={0,1,2,3,3,4,4}; static unsigned int ip[MAXDIM+1]={0,0,1,1,2,1,4}; static unsigned int iv[MAXDIM*MAXBIT+1]={ 0,1,1,1,1,1,1,3,1,3,3,1,1,5,7,7,3,3,5,15,11,5,15,13,9}; if (n < 0) { for (j=1,k=0;j<=MAXBIT;j++,k+=MAXDIM) iu[j] = &iv[k]; for (k=1;k<=MAXDIM;k++) { for (j=1;j<=(int)mdeg[k];j++) iu[j][k] <<= (MAXBIT-j); for (j=mdeg[k]+1;j<=MAXBIT;j++) { ipp=ip[k]; i=iu[j-mdeg[k]][k]; i ^= (i >> mdeg[k]); for (l=mdeg[k]-1;l>=1;l--) { if (ipp & 1) i ^= iu[j-l][k]; ipp >>= 1; } iu[j][k]=i; } } in=0; } else { im=in; for (j=1;j<=MAXBIT;j++) { if (!(im & 1)) break; im >>= 1; } assert(j <= MAXBIT); im=(j-1)*MAXDIM; for (k=1;k<=n;k++) { ix[k] ^= iv[im+k]; x[k-1]=(int)(ix[k]>>14)-32768; } in++; } } static float MC_Norms[MC_N_VECT][3]; static int MC_Inited=0; void MC_Init() { int x[3]; int sq,num=0; int tnum=0; float d; MC_Inited=1; sobseq(-3,0); while (num17000*17000) continue; d=1.0f/(float)sqrt((float)sq); MC_Norms[num][0]=d*((float)(x[0])); MC_Norms[num][1]=d*((float)(x[1])); MC_Norms[num][2]=d*((float)(x[2])); num++; } #if 0 printf("%d trys to get %d vals\n",tnum,num); { int i,j; float mn=5.0f,mx; for (i=0;imx) mx=d; } } if (mxmx) { mx=d; mxat=i; } } return mxat; } void MC_Compress(const float mat[3][4],unsigned char * comp) { int i,val; if (!MC_Inited) MC_Init(); for (i=0;i=(1<=(1<=(1<>=MC_SHIFT_X; uval&=MC_MASK_X; val=(int)uval; val-=1<<(MC_BITS_X-1); mat[0][3]=((float)(val))*MC_SCALE_X; uval=*(unsigned int *)(comp+MC_POS_Y); uval>>=MC_SHIFT_Y; uval&=MC_MASK_Y; val=(int)uval; val-=1<<(MC_BITS_Y-1); mat[1][3]=((float)(val))*MC_SCALE_Y; uval=*(unsigned int *)(comp+MC_POS_Z); uval>>=MC_SHIFT_Z; uval&=MC_MASK_Z; val=(int)uval; val-=1<<(MC_BITS_Z-1); mat[2][3]=((float)(val))*MC_SCALE_Z; uval=*(unsigned int *)(comp+MC_POS_V1); uval>>=MC_SHIFT_V1; uval&=MC_MASK_VECT; mat[0][0]=MC_Norms[uval][0]; mat[0][1]=MC_Norms[uval][1]; mat[0][2]=MC_Norms[uval][2]; uval=*(unsigned int *)(comp+MC_POS_V2); uval>>=MC_SHIFT_V2; uval&=MC_MASK_VECT; mat[1][0]=MC_Norms[uval][0]; mat[1][1]=MC_Norms[uval][1]; mat[1][2]=MC_Norms[uval][2]; uval=*(unsigned int *)(comp+MC_POS_V3); uval>>=MC_SHIFT_V3; uval&=MC_MASK_VECT; mat[2][0]=MC_Norms[uval][0]; mat[2][1]=MC_Norms[uval][1]; mat[2][2]=MC_Norms[uval][2]; }