]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake2/qdata_heretic2/animcomp.c
Merge commit '9fed37bae007bd5e53963ec67e925381609a2980' into garux-merge
[xonotic/netradiant.git] / tools / quake2 / qdata_heretic2 / animcomp.c
index 7e0c96d17fcec8fb7a61fabad65d4696b9fde8f4..a7619325cba14b7fbf0548106f3c9956e9e30804 100644 (file)
-/*\r
-Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
-For a list of contributors, see the accompanying CONTRIBUTORS file.\r
-\r
-This file is part of GtkRadiant.\r
-\r
-GtkRadiant is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-GtkRadiant is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with GtkRadiant; if not, write to the Free Software\r
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
-*/\r
-\r
-\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <math.h>\r
-#include <memory.h>\r
-#include "animcomp.h"\r
-\r
-\r
-void   *SafeMalloc(size_t n, char *desc);\r
-\r
-\r
-\r
-float *matrix;\r
-float *delta;\r
-float *best;\r
-float *comp;\r
-float *tcomp;\r
-float *bestcomp;\r
-float *frames;\r
-float *base;\r
-\r
-int MatWidth;\r
-int MatHeight;\r
-int CFrameSize;\r
-int nFrames;\r
-\r
-\r
-void AnimCompressInit(int nframes,int nVerts,int CompressedFrameSize)\r
-{\r
-       nFrames=nframes;\r
-       MatWidth=nVerts*3;\r
-       MatHeight=CompressedFrameSize;\r
-       CFrameSize=CompressedFrameSize;\r
-       matrix=(float *)SafeMalloc(MatWidth*MatHeight*sizeof(float), "AnimCompressInit");\r
-       best=(float *)SafeMalloc(MatWidth*MatHeight*sizeof(float), "AnimCompressInit");\r
-       delta=(float *)SafeMalloc(MatWidth*MatHeight*sizeof(float), "AnimCompressInit");\r
-       comp=(float *)SafeMalloc(CFrameSize*nFrames*sizeof(float), "AnimCompressInit");\r
-       tcomp=(float *)SafeMalloc(CFrameSize*nFrames*sizeof(float), "AnimCompressInit");\r
-       bestcomp=(float *)SafeMalloc(CFrameSize*nFrames*sizeof(float), "AnimCompressInit");\r
-       base=(float *)SafeMalloc(MatWidth*sizeof(float), "AnimCompressInit");\r
-       frames=(float *)SafeMalloc(MatWidth*nFrames*sizeof(float), "AnimCompressInit");\r
-}\r
-\r
-void AnimSetFrame(int frame,int index,float x,float y,float z)\r
-{\r
-       frames[frame*MatWidth+index*3]=x;\r
-       frames[frame*MatWidth+index*3+1]=y;\r
-       frames[frame*MatWidth+index*3+2]=z;\r
-}\r
-\r
-typedef struct \r
-{\r
-       int index;\r
-       float val;\r
-} SORTP;\r
-\r
-\r
-#define F_RANDOM (((float)rand())/(float)RAND_MAX)\r
-\r
-extern void DOsvd(float *a,float *res,float *comp,float *values,int nframes,int framesize,int compressedsize);\r
-\r
-void AnimCompressDoit()\r
-{\r
-       float compression;\r
-       float *rescale;\r
-       float *ans;\r
-       float maxdev;\r
-       float avedev;\r
-       float tmp;\r
-       int j,k,l,numave;\r
-\r
-       for (k=0;k<MatWidth;k++)\r
-               base[k]=0.0f;\r
-       for (j=0;j<nFrames;j++)\r
-               for (k=0;k<MatWidth;k++)\r
-                       base[k]+=frames[j*MatWidth+k];\r
-       tmp=1.0f/(float)nFrames;\r
-       for (k=0;k<MatWidth;k++)\r
-               base[k]*=tmp;\r
-       for (j=0;j<nFrames;j++)\r
-               for (k=0;k<MatWidth;k++)\r
-                       frames[j*MatWidth+k]-=base[k];\r
-\r
-       ans=(float *)SafeMalloc(sizeof(float)*MatWidth, "AnimCompressDoit");\r
-       rescale=(float *)SafeMalloc(sizeof(float)*CFrameSize, "AnimCompressDoit");\r
-       DOsvd(frames,best,bestcomp,rescale,nFrames,MatWidth,MatHeight);\r
-       avedev=0.0;\r
-       for (l=0;l<CFrameSize;l++)\r
-               avedev+=rescale[l];\r
-       for (l=0;l<CFrameSize;l++)\r
-               printf("%3.1f ",100.0f*rescale[l]/avedev);\r
-       printf("\n");\r
-       for (j=0;j<nFrames;j++)\r
-       {\r
-               for (l=0;l<CFrameSize;l++)\r
-               {\r
-                       bestcomp[j*CFrameSize+l]=0.0;\r
-                       for (k=0;k<MatWidth;k++)\r
-                               bestcomp[j*CFrameSize+l]+=best[l*MatWidth+k]*frames[j*MatWidth+k];\r
-               }\r
-       }\r
-       numave=0;\r
-       avedev=0.0;\r
-       maxdev=0.0;\r
-       for (j=0;j<nFrames;j++)\r
-       {\r
-               for (k=0;k<MatWidth;k++)\r
-               {\r
-                       ans[k]=0.0;\r
-                       for (l=0;l<CFrameSize;l++)\r
-                               ans[k]+=best[l*MatWidth+k]*bestcomp[j*CFrameSize+l];\r
-                       ans[k]-=frames[j*MatWidth+k];\r
-                       tmp=(float)fabs(ans[k]);\r
-                       if (tmp>maxdev)\r
-                               maxdev=tmp;\r
-                       avedev+=tmp;\r
-                       numave++;\r
-               }\r
-       }\r
-       avedev/=(float)numave;\r
-printf("%f Max Deviation (inches)  %f Ave Dev. (inches)\n",maxdev,avedev);\r
-printf("%d bytes original size\n",MatWidth*nFrames);\r
-printf("%d bytes of overhead\n",MatWidth*MatHeight);\r
-printf("%d bytes/frame * %d frames = %d bytes\n",CFrameSize,nFrames,CFrameSize*nFrames);\r
-       compression=(float)(MatWidth*MatHeight+CFrameSize*nFrames+MatWidth);\r
-       compression/=(float)(MatWidth*nFrames);\r
-printf("Overall compression = %f %%\n",100.0f-100.0f*compression);\r
-       compression=(float)(CFrameSize);\r
-       compression/=(float)(MatWidth);\r
-printf("frame size compression = %f %%\n",100.0f-100.0f*compression);\r
-       free(rescale);\r
-       free(ans);\r
-}\r
-\r
-void AnimCompressToBytes(float *trans,float *scale,char *mat,char *ccomp,unsigned char *cbase,float *cscale,float *coffset,float *bmin,float *bmax)\r
-{\r
-       int k,l,nv,j;\r
-       float maxdev;\r
-       float avedev;\r
-       float tmp;\r
-       int numave;\r
-       float t,mx;\r
-       float *ans;\r
-\r
-\r
-       nv=MatWidth/3;\r
-\r
-       trans[0]=1E30f;\r
-       scale[0]=-1E30f;\r
-       trans[1]=1E30f;\r
-       scale[1]=-1E30f;\r
-       trans[2]=1E30f;\r
-       scale[2]=-1E30f;\r
-       for (k=0;k<MatWidth;k+=3)\r
-       {\r
-               if (base[k]>scale[0])\r
-                       scale[0]=base[k];\r
-               if (base[k]<trans[0])\r
-                       trans[0]=base[k];\r
-\r
-               if (base[k+1]>scale[1])\r
-                       scale[1]=base[k+1];\r
-               if (base[k+1]<trans[1])\r
-                       trans[1]=base[k+1];\r
-\r
-               if (base[k+2]>scale[2])\r
-                       scale[2]=base[k+2];\r
-               if (base[k+2]<trans[2])\r
-                       trans[2]=base[k+2];\r
-       }\r
-\r
-       scale[0]-=trans[0];\r
-       scale[1]-=trans[1];\r
-       scale[2]-=trans[2];\r
-       scale[0]/=255.0f;\r
-       scale[1]/=255.0f;\r
-       scale[2]/=255.0f;\r
-       for (k=0;k<MatWidth;k+=3)\r
-       {\r
-               t=(base[k]-trans[0])/scale[0];\r
-               if (t<0.0f)\r
-                       t=0.0f;\r
-               if (t>255.0f)\r
-                       t=255.0f;\r
-               cbase[k]=(unsigned char)t;\r
-\r
-               t=(base[k+1]-trans[1])/scale[1];\r
-               if (t<0.0f)\r
-                       t=0.0f;\r
-               if (t>255.0f)\r
-                       t=255.0f;\r
-               cbase[k+1]=(unsigned char)t;\r
-\r
-               t=(base[k+2]-trans[2])/scale[2];\r
-               if (t<0.0f)\r
-                       t=0.0f;\r
-               if (t>255.0f)\r
-                       t=255.0f;\r
-               cbase[k+2]=(unsigned char)t;\r
-       }\r
-       for (l=0;l<MatHeight;l++)\r
-       {\r
-               mx=0.0;\r
-               for (k=0;k<MatWidth;k++)\r
-               {\r
-                       if (fabs(best[l*MatWidth+k])>mx)\r
-                               mx=(float)fabs(best[l*MatWidth+k]);\r
-               }\r
-               if (mx>1E-8)\r
-               {\r
-                       mx/=127.0f;\r
-                       coffset[l]=1E30f;\r
-                       cscale[l]=-1E30f;\r
-                       for (j=0;j<nFrames;j++)\r
-                       {\r
-                               bestcomp[j*MatHeight+l]*=mx;\r
-                               if (bestcomp[j*MatHeight+l]>cscale[l])\r
-                                       cscale[l]=bestcomp[j*MatHeight+l];\r
-                               if (bestcomp[j*MatHeight+l]<coffset[l])\r
-                                       coffset[l]=bestcomp[j*MatHeight+l];\r
-                       }\r
-                       cscale[l]-=coffset[l];\r
-                       if (cscale[l]>1E-10)\r
-                       {\r
-                               for (j=0;j<nFrames;j++)\r
-                               {\r
-                                       tmp=254.0f*(bestcomp[j*MatHeight+l]-coffset[l])/cscale[l]-127.0f;\r
-                                       if (tmp>127.0f)\r
-                                               tmp=127.0f;\r
-                                       if (tmp<-127.0f)\r
-                                               tmp=-127.0f;\r
-                                       ccomp[j*MatHeight+l]=(char)floor(tmp+0.5);\r
-                               }\r
-                               coffset[l]+=cscale[l]*127.0f/254.0f;\r
-                               cscale[l]/=254.0f;\r
-                       }\r
-                       else\r
-                       {\r
-                               cscale[l]=1.0f;\r
-                               coffset[l]=0.0f;\r
-                               for (j=0;j<nFrames;j++)\r
-                                       ccomp[j*MatHeight+l]=0;\r
-                       }\r
-                       mx=1.0f/mx;\r
-                       for (k=0;k<MatWidth;k++)\r
-                       {\r
-                               tmp=best[l*MatWidth+k]*mx;\r
-                               if (tmp>127.0f)\r
-                                       tmp=127.0f;\r
-                               if (tmp<-127.0f)\r
-                                       tmp=-127.0f;\r
-                               mat[k*MatHeight+l]=(char)floor(tmp+0.5);\r
-                       }\r
-               }\r
-               else\r
-               {\r
-                       cscale[l]=1.0f;\r
-                       coffset[l]=0.0f;\r
-                       for (j=0;j<nFrames;j++)\r
-                               ccomp[j*MatHeight+l]=0;\r
-                       for (k=0;k<MatWidth;k++)\r
-                               mat[k*MatHeight+l]=0;\r
-               }\r
-       }\r
-       bmin[0]=1E30f;\r
-       bmin[1]=1E30f;\r
-       bmin[2]=1E30f;\r
-       bmax[0]=-1E30f;\r
-       bmax[1]=-1E30f;\r
-       bmax[2]=-1E30f;\r
-       numave=0;\r
-       avedev=0.0;\r
-       maxdev=0.0;\r
-       ans=(float *)SafeMalloc(sizeof(float)*MatWidth, "AnimCompressToBytes");\r
-       for (j=0;j<nFrames;j++)\r
-       {\r
-               for (k=0;k<MatWidth;k++)\r
-               {\r
-                       ans[k]=0.0;\r
-                       for (l=0;l<CFrameSize;l++)\r
-                               ans[k]+=(float)(mat[l+k*MatHeight])*((float)(ccomp[j*CFrameSize+l])*cscale[l]+coffset[l]);\r
-                       ans[k]+=(float)(cbase[k])*scale[k%3]+trans[k%3];\r
-                       tmp=(float)fabs(ans[k]-frames[j*MatWidth+k]-base[k]);\r
-                       if (tmp>maxdev)\r
-                               maxdev=tmp;\r
-                       avedev+=tmp;\r
-                       numave++;\r
-\r
-                       if (bmin[k%3]>ans[k])\r
-                               bmin[k%3]=ans[k];\r
-                       if (bmax[k%3]<ans[k])\r
-                               bmax[k%3]=ans[k];\r
-               }\r
-       }\r
-       avedev/=(float)numave;\r
-printf("%f Max Deviation (inches)  %f Ave Dev. (inches)\n",maxdev,avedev);\r
-       free(ans);\r
-}\r
-\r
-void AnimCompressGetMatrix(float *mat)\r
-{\r
-       int k,l;\r
-       for (k=0;k<MatWidth;k++)\r
-               for (l=0;l<MatHeight;l++)\r
-                       mat[k*MatHeight+l]=best[l*MatWidth+k];\r
-}\r
-\r
-void AnimCompressGetFrames(float *mat)\r
-{\r
-       memcpy(mat,bestcomp,CFrameSize*nFrames*sizeof(float));\r
-}\r
-\r
-void AnimCompressGetBase(int i,float *x,float *y,float *z)\r
-{\r
-       *x=base[i*3];\r
-       *y=base[i*3+1];\r
-       *z=base[i*3+2];\r
-}\r
-\r
-void AnimCompressEnd()\r
-{\r
-       free(matrix);\r
-       free(best);\r
-       free(delta);\r
-       free(comp);\r
-       free(tcomp);\r
-       free(bestcomp);\r
-       free(base);\r
-       free(frames);\r
-}\r
+/*
+   Copyright (C) 1999-2007 id Software, Inc. and contributors.
+   For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+   This file is part of GtkRadiant.
+
+   GtkRadiant is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   GtkRadiant is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <memory.h>
+#include "animcomp.h"
+
+
+void    *SafeMalloc( size_t n, char *desc );
+
+
+
+float *matrix;
+float *delta;
+float *best;
+float *comp;
+float *tcomp;
+float *bestcomp;
+float *frames;
+float *base;
+
+int MatWidth;
+int MatHeight;
+int CFrameSize;
+int nFrames;
+
+
+void AnimCompressInit( int nframes,int nVerts,int CompressedFrameSize ){
+       nFrames = nframes;
+       MatWidth = nVerts * 3;
+       MatHeight = CompressedFrameSize;
+       CFrameSize = CompressedFrameSize;
+       matrix = (float *)SafeMalloc( MatWidth * MatHeight * sizeof( float ), "AnimCompressInit" );
+       best = (float *)SafeMalloc( MatWidth * MatHeight * sizeof( float ), "AnimCompressInit" );
+       delta = (float *)SafeMalloc( MatWidth * MatHeight * sizeof( float ), "AnimCompressInit" );
+       comp = (float *)SafeMalloc( CFrameSize * nFrames * sizeof( float ), "AnimCompressInit" );
+       tcomp = (float *)SafeMalloc( CFrameSize * nFrames * sizeof( float ), "AnimCompressInit" );
+       bestcomp = (float *)SafeMalloc( CFrameSize * nFrames * sizeof( float ), "AnimCompressInit" );
+       base = (float *)SafeMalloc( MatWidth * sizeof( float ), "AnimCompressInit" );
+       frames = (float *)SafeMalloc( MatWidth * nFrames * sizeof( float ), "AnimCompressInit" );
+}
+
+void AnimSetFrame( int frame,int index,float x,float y,float z ){
+       frames[frame * MatWidth + index * 3] = x;
+       frames[frame * MatWidth + index * 3 + 1] = y;
+       frames[frame * MatWidth + index * 3 + 2] = z;
+}
+
+typedef struct
+{
+       int index;
+       float val;
+} SORTP;
+
+
+#define F_RANDOM ( ( (float)rand() ) / (float)RAND_MAX )
+
+extern void DOsvd( float *a,float *res,float *comp,float *values,int nframes,int framesize,int compressedsize );
+
+void AnimCompressDoit(){
+       float compression;
+       float *rescale;
+       float *ans;
+       float maxdev;
+       float avedev;
+       float tmp;
+       int j,k,l,numave;
+
+       for ( k = 0; k < MatWidth; k++ )
+               base[k] = 0.0f;
+       for ( j = 0; j < nFrames; j++ )
+               for ( k = 0; k < MatWidth; k++ )
+                       base[k] += frames[j * MatWidth + k];
+       tmp = 1.0f / (float)nFrames;
+       for ( k = 0; k < MatWidth; k++ )
+               base[k] *= tmp;
+       for ( j = 0; j < nFrames; j++ )
+               for ( k = 0; k < MatWidth; k++ )
+                       frames[j * MatWidth + k] -= base[k];
+
+       ans = (float *)SafeMalloc( sizeof( float ) * MatWidth, "AnimCompressDoit" );
+       rescale = (float *)SafeMalloc( sizeof( float ) * CFrameSize, "AnimCompressDoit" );
+       DOsvd( frames,best,bestcomp,rescale,nFrames,MatWidth,MatHeight );
+       avedev = 0.0;
+       for ( l = 0; l < CFrameSize; l++ )
+               avedev += rescale[l];
+       for ( l = 0; l < CFrameSize; l++ )
+               printf( "%3.1f ",100.0f * rescale[l] / avedev );
+       printf( "\n" );
+       for ( j = 0; j < nFrames; j++ )
+       {
+               for ( l = 0; l < CFrameSize; l++ )
+               {
+                       bestcomp[j * CFrameSize + l] = 0.0;
+                       for ( k = 0; k < MatWidth; k++ )
+                               bestcomp[j * CFrameSize + l] += best[l * MatWidth + k] * frames[j * MatWidth + k];
+               }
+       }
+       numave = 0;
+       avedev = 0.0;
+       maxdev = 0.0;
+       for ( j = 0; j < nFrames; j++ )
+       {
+               for ( k = 0; k < MatWidth; k++ )
+               {
+                       ans[k] = 0.0;
+                       for ( l = 0; l < CFrameSize; l++ )
+                               ans[k] += best[l * MatWidth + k] * bestcomp[j * CFrameSize + l];
+                       ans[k] -= frames[j * MatWidth + k];
+                       tmp = (float)fabs( ans[k] );
+                       if ( tmp > maxdev ) {
+                               maxdev = tmp;
+                       }
+                       avedev += tmp;
+                       numave++;
+               }
+       }
+       avedev /= (float)numave;
+       printf( "%f Max Deviation (inches)  %f Ave Dev. (inches)\n",maxdev,avedev );
+       printf( "%d bytes original size\n",MatWidth * nFrames );
+       printf( "%d bytes of overhead\n",MatWidth * MatHeight );
+       printf( "%d bytes/frame * %d frames = %d bytes\n",CFrameSize,nFrames,CFrameSize * nFrames );
+       compression = (float)( MatWidth * MatHeight + CFrameSize * nFrames + MatWidth );
+       compression /= (float)( MatWidth * nFrames );
+       printf( "Overall compression = %f %%\n",100.0f - 100.0f * compression );
+       compression = (float)( CFrameSize );
+       compression /= (float)( MatWidth );
+       printf( "frame size compression = %f %%\n",100.0f - 100.0f * compression );
+       free( rescale );
+       free( ans );
+}
+
+void AnimCompressToBytes( float *trans,float *scale,char *mat,char *ccomp,unsigned char *cbase,float *cscale,float *coffset,float *bmin,float *bmax ){
+       int k,l,nv,j;
+       float maxdev;
+       float avedev;
+       float tmp;
+       int numave;
+       float t,mx;
+       float *ans;
+
+
+       nv = MatWidth / 3;
+
+       trans[0] = 1E30f;
+       scale[0] = -1E30f;
+       trans[1] = 1E30f;
+       scale[1] = -1E30f;
+       trans[2] = 1E30f;
+       scale[2] = -1E30f;
+       for ( k = 0; k < MatWidth; k += 3 )
+       {
+               if ( base[k] > scale[0] ) {
+                       scale[0] = base[k];
+               }
+               if ( base[k] < trans[0] ) {
+                       trans[0] = base[k];
+               }
+
+               if ( base[k + 1] > scale[1] ) {
+                       scale[1] = base[k + 1];
+               }
+               if ( base[k + 1] < trans[1] ) {
+                       trans[1] = base[k + 1];
+               }
+
+               if ( base[k + 2] > scale[2] ) {
+                       scale[2] = base[k + 2];
+               }
+               if ( base[k + 2] < trans[2] ) {
+                       trans[2] = base[k + 2];
+               }
+       }
+
+       scale[0] -= trans[0];
+       scale[1] -= trans[1];
+       scale[2] -= trans[2];
+       scale[0] /= 255.0f;
+       scale[1] /= 255.0f;
+       scale[2] /= 255.0f;
+       for ( k = 0; k < MatWidth; k += 3 )
+       {
+               t = ( base[k] - trans[0] ) / scale[0];
+               if ( t < 0.0f ) {
+                       t = 0.0f;
+               }
+               if ( t > 255.0f ) {
+                       t = 255.0f;
+               }
+               cbase[k] = (unsigned char)t;
+
+               t = ( base[k + 1] - trans[1] ) / scale[1];
+               if ( t < 0.0f ) {
+                       t = 0.0f;
+               }
+               if ( t > 255.0f ) {
+                       t = 255.0f;
+               }
+               cbase[k + 1] = (unsigned char)t;
+
+               t = ( base[k + 2] - trans[2] ) / scale[2];
+               if ( t < 0.0f ) {
+                       t = 0.0f;
+               }
+               if ( t > 255.0f ) {
+                       t = 255.0f;
+               }
+               cbase[k + 2] = (unsigned char)t;
+       }
+       for ( l = 0; l < MatHeight; l++ )
+       {
+               mx = 0.0;
+               for ( k = 0; k < MatWidth; k++ )
+               {
+                       if ( fabs( best[l * MatWidth + k] ) > mx ) {
+                               mx = (float)fabs( best[l * MatWidth + k] );
+                       }
+               }
+               if ( mx > 1E-8 ) {
+                       mx /= 127.0f;
+                       coffset[l] = 1E30f;
+                       cscale[l] = -1E30f;
+                       for ( j = 0; j < nFrames; j++ )
+                       {
+                               bestcomp[j * MatHeight + l] *= mx;
+                               if ( bestcomp[j * MatHeight + l] > cscale[l] ) {
+                                       cscale[l] = bestcomp[j * MatHeight + l];
+                               }
+                               if ( bestcomp[j * MatHeight + l] < coffset[l] ) {
+                                       coffset[l] = bestcomp[j * MatHeight + l];
+                               }
+                       }
+                       cscale[l] -= coffset[l];
+                       if ( cscale[l] > 1E-10 ) {
+                               for ( j = 0; j < nFrames; j++ )
+                               {
+                                       tmp = 254.0f * ( bestcomp[j * MatHeight + l] - coffset[l] ) / cscale[l] - 127.0f;
+                                       if ( tmp > 127.0f ) {
+                                               tmp = 127.0f;
+                                       }
+                                       if ( tmp < -127.0f ) {
+                                               tmp = -127.0f;
+                                       }
+                                       ccomp[j * MatHeight + l] = (char)floor( tmp + 0.5 );
+                               }
+                               coffset[l] += cscale[l] * 127.0f / 254.0f;
+                               cscale[l] /= 254.0f;
+                       }
+                       else
+                       {
+                               cscale[l] = 1.0f;
+                               coffset[l] = 0.0f;
+                               for ( j = 0; j < nFrames; j++ )
+                                       ccomp[j * MatHeight + l] = 0;
+                       }
+                       mx = 1.0f / mx;
+                       for ( k = 0; k < MatWidth; k++ )
+                       {
+                               tmp = best[l * MatWidth + k] * mx;
+                               if ( tmp > 127.0f ) {
+                                       tmp = 127.0f;
+                               }
+                               if ( tmp < -127.0f ) {
+                                       tmp = -127.0f;
+                               }
+                               mat[k * MatHeight + l] = (char)floor( tmp + 0.5 );
+                       }
+               }
+               else
+               {
+                       cscale[l] = 1.0f;
+                       coffset[l] = 0.0f;
+                       for ( j = 0; j < nFrames; j++ )
+                               ccomp[j * MatHeight + l] = 0;
+                       for ( k = 0; k < MatWidth; k++ )
+                               mat[k * MatHeight + l] = 0;
+               }
+       }
+       bmin[0] = 1E30f;
+       bmin[1] = 1E30f;
+       bmin[2] = 1E30f;
+       bmax[0] = -1E30f;
+       bmax[1] = -1E30f;
+       bmax[2] = -1E30f;
+       numave = 0;
+       avedev = 0.0;
+       maxdev = 0.0;
+       ans = (float *)SafeMalloc( sizeof( float ) * MatWidth, "AnimCompressToBytes" );
+       for ( j = 0; j < nFrames; j++ )
+       {
+               for ( k = 0; k < MatWidth; k++ )
+               {
+                       ans[k] = 0.0;
+                       for ( l = 0; l < CFrameSize; l++ )
+                               ans[k] += (float)( mat[l + k * MatHeight] ) * ( (float)( ccomp[j * CFrameSize + l] ) * cscale[l] + coffset[l] );
+                       ans[k] += (float)( cbase[k] ) * scale[k % 3] + trans[k % 3];
+                       tmp = (float)fabs( ans[k] - frames[j * MatWidth + k] - base[k] );
+                       if ( tmp > maxdev ) {
+                               maxdev = tmp;
+                       }
+                       avedev += tmp;
+                       numave++;
+
+                       if ( bmin[k % 3] > ans[k] ) {
+                               bmin[k % 3] = ans[k];
+                       }
+                       if ( bmax[k % 3] < ans[k] ) {
+                               bmax[k % 3] = ans[k];
+                       }
+               }
+       }
+       avedev /= (float)numave;
+       printf( "%f Max Deviation (inches)  %f Ave Dev. (inches)\n",maxdev,avedev );
+       free( ans );
+}
+
+void AnimCompressGetMatrix( float *mat ){
+       int k,l;
+       for ( k = 0; k < MatWidth; k++ )
+               for ( l = 0; l < MatHeight; l++ )
+                       mat[k * MatHeight + l] = best[l * MatWidth + k];
+}
+
+void AnimCompressGetFrames( float *mat ){
+       memcpy( mat,bestcomp,CFrameSize * nFrames * sizeof( float ) );
+}
+
+void AnimCompressGetBase( int i,float *x,float *y,float *z ){
+       *x = base[i * 3];
+       *y = base[i * 3 + 1];
+       *z = base[i * 3 + 2];
+}
+
+void AnimCompressEnd(){
+       free( matrix );
+       free( best );
+       free( delta );
+       free( comp );
+       free( tcomp );
+       free( bestcomp );
+       free( base );
+       free( frames );
+}