#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "/home/mq/Quasi-3D/IRCS/Quasi3D/libQ3D.h"
/*#include "./libQ3D.h"*/
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>

#define INTSIZE 10  
char *itoa(int n);

char STKFileName[1024], OptionsFileName[1024];
char TGAFileName[1024];
unsigned long Width=500, Height=500, StartingLine=0, EndingLine=499;
int SuperSamplingFactor=1, Verbose;

int i;
double haze=0;

static unsigned char header_in[4],header_out[18];
static unsigned char packet_in[512];
static unsigned char packet_out[6];
static long total_read, total_written;
static FILE *infile, *outfile;

#define RAW 0
#define RLE 1

static int NoAlpha;

void progress(double ratio)
{
  printf("\r%d%%",(int)(100*ratio)); 
  fflush(stdout);
}

void message(char *text)
{
  printf("%s\n",text);
}


void process_args(int argc, char **argv)
{
  int i,  argI=0, argO=0;
  
  if (argc==1) {
    printf("options:\n");
    printf("  -i [name]   : STK input file\n");
    printf("  -o [name]   : TGA output file\n");
    printf("  -w [number] : Image width (default: 500)\n");
    printf("  -h [number] : Image height (default: 500)\n");
    printf("  -a [number] : Starting scan-line (default: 0)\n");
    printf("  -e [number] : Ending scan-line (default: height-1)\n");
    printf("  -a [number] : Antialiasing factor (default: 1)\n");
    printf("  -x [number] : Haze (default: )\n");
/********    printf("  -v [number] : Verbosity level (default: 0)\n");****/
    exit(-1);
  }

  for (i=1; i<argc; i++) {
    if (!strcmp(argv[i],"-i")) {
      strcpy(STKFileName,argv[++i]);
      argI = 1;
    }
    else if (!strcmp(argv[i],"-o")) {
      strcpy(TGAFileName,argv[++i]);
      argO = 1;
    }
    else if (!strcmp(argv[i],"-w")) {
      Width = atoi(argv[++i]);
    }
    else if (!strcmp(argv[i],"-h")) {
      Height = atoi(argv[++i]);
    }
    else if (!strcmp(argv[i],"-s")) {
      StartingLine = atoi(argv[++i]);
    }
    else if (!strcmp(argv[i],"-e")) {
      EndingLine = atoi(argv[++i]);
    }
    else if (!strcmp(argv[i],"-a")) {
      SuperSamplingFactor = atoi(argv[++i]);
    }
    else if (!strcmp(argv[i],"-x")) {
      haze = atof(argv[++i]);
    }
    else if (!strcmp(argv[i],"-v")) {
      Verbose = atoi(argv[++i]);
    }
  }

  if (argI==0) {
    fprintf(stderr,"STK input file not specified (use: -i [filename])\n");
    exit(-1);
  }
  if (argO==0) {
    fprintf(stderr,"TGA output file not specified (use: -o [filename])\n");
    exit(-2);
  }    

  if (EndingLine == 0)
    EndingLine = Height-1;


/********  if (Verbose) {
    printf("Input file: %s\n",STKFileName);
    printf("Output file: %s\n",ETGAFileName);
    printf("Size: %ld x %ld\n",Width, Height);
    printf("Starting line: %ld, Ending Line: %ld\n",StartingLine, EndingLine);
    printf("Antialising: ");
    if (SuperSamplingFactor>1) 
      printf("%d\n",SuperSamplingFactor);
    else
      printf("none\n");
    printf("Verbose Level: %d\n",Verbose);
  }
  }******/
}

static void translate_packet(const int type)
{
  int len; /* length of packet -1 */
  int i,j;


  switch(type) {
  case RLE:
    packet_out[0]=255; /* i.e. 128 pixel long packet + bit 7 set to 1 */
    len =(packet_in[0] - 128) + (packet_in[1]<<7) + 1;
    total_read += len;


    /* read packet pixel */
    fread(packet_in, 1, 4, infile);
    packet_out[1]=packet_in[0];
    packet_out[2]=packet_in[1];
    packet_out[3]=packet_in[2];
    packet_out[4]=packet_in[3];

    /*    if (verbose==2)
      printf("in: RLE packet (length=%d, colour=%d %d %d %d)\n",len,
      packet_in[0],packet_in[1],packet_in[2],packet_in[3]);*/

    
    for (i=0; i<len/128; i++) {
      if (NoAlpha)
	fwrite(packet_out,1,4,outfile);
      else
	fwrite(packet_out,1,5,outfile);
      total_written += 128;
      /*      if (verbose==2)
	      printf("out: RLE packet (length=128)\n");*/
    }
    

    /* last packet */
    if (len %= 128) {
      packet_out[0] = (unsigned char)(len - 1 + 128);
      if (NoAlpha)
	fwrite(packet_out,1,4,outfile);
      else
	fwrite(packet_out,1,5,outfile);
      total_written += len;
      /*  if (verbose==2)
	  printf("out: RLE packet (length=%d)\n",len);*/
    }
    break;

  case RAW:
    packet_out[0]=127; /* i.e. 128 pixel long packet + bit 7 set to 0 */
    len =(packet_in[0]) + (packet_in[1]<<7) + 1;
    total_read += len;

    /*    if (verbose==2)
	  printf("in: RAW packet (length=%d)\n",len);*/

    for (i=0; i<len/128; i++) {
      /* header */
      packet_out[0]=127; /* i.e. 128 pixel long packet + bit 7 set to 0 */
      fwrite(packet_out,1,1,outfile);

      /* 128 pixels */
      fread(packet_in,1,128*4,infile);

      for (j=0;j<128;j++) {
	packet_out[0]=packet_in[j*4];
	packet_out[1]=packet_in[j*4+1];
	packet_out[2]=packet_in[j*4+2];
	if (NoAlpha) {
	  fwrite(packet_out,1,3,outfile);
	}
	else {
	  packet_out[3]=packet_in[j*4+3];
	  fwrite(packet_out,1,4,outfile);
	}

      }
      total_written += 128;
      
      /*      if (verbose==2)
	      printf("out: RAW packet (length=128)\n");*/
    }
     

    /* last packet */
    if (len %= 128) {
      packet_out[0]= (unsigned char)(len - 1);
      fwrite(packet_out,1,1,outfile);

      fread(packet_in,1,(unsigned int)(4*len),infile);

      for (j=0;j<len;j++) {
	packet_out[0]=packet_in[j*4];
	packet_out[1]=packet_in[j*4+1];
	packet_out[2]=packet_in[j*4+2];
	if (NoAlpha)
	  fwrite(packet_out,1,3,outfile);
	else {
	  packet_out[3]=packet_in[j*4+3];
	  fwrite(packet_out,1,4,outfile);
	}
      }
      /*      if (verbose==2)
	      printf("out: RAW packet (length=%d)\n",len);*/
      
      total_written += len;
    }
    break;
  }
}	

main(int argc, char **argv)
{

   FILE *fp, *stkFile;
   char *index, *filename;
   int  j, k, g=0, h=0, CFGLineNumber=0, cameraNumber=0, scriptNumber=0, frameNumber=0;
   char str[250][100];
   char celName[20][30];
   char *t1, *t2, *t3, *t4;
   static int celNumber=0, stkFileNumber=0;
   double celRotationX[30], celRotationY[30], celRotationZ[30];
   double celTranslationX[30], celTranslationY[30], celTranslationZ[30];
   double RotationX, RotationY, RotationZ;
   double TranslationX, TranslationY, TranslationZ;
   double temp1, temp2, temp3, temp4, tempx, tempy, tempz, minus, TX, TY, TZ, v, l;
   double tmp[3];
   double total1,total2;
   double currentpx,currentpy,currentpz,currentdx,currentdy,currentdz,currentup,currentzoom,current1,current2;
   int judgex,judgey,judgez;
   

   IR_Stack stack;
   IR_Cel c;
   IR_Matrix4 celRotateX, celRotateY, celRotateZ, celRotate;
   IR_Matrix4 transform1, transform2;
   IR_Matrix4 translate1, translate2, celTranslate, celTransform;
   IR_Matrix4 celspacetransform[30];
   IR_Matrix4 celinitialrotation[30];
   IR_Matrix4 identity4 = {{1.0, 0.0, 0.0, 0.0},
			    {0.0, 1.0, 0.0, 0.0},
			    {0.0, 0.0, 1.0, 0.0},
			    {0.0, 0.0, 0.0, 1.0}};

     
   IR_ImageInfo iminfo;

   typedef struct 
   {
       double x, y, z;
       }IR_Point3;

   typedef struct 
   {
      char *name;
      IR_Point3 position;
      IR_Point3 direction;
      double up;
      double zoom;   
      }CAMERA;

   CAMERA camera[50],start,end;   

   typedef struct
   {
      int startFrame;
      int endFrame;
      char *startCamera;
      char *endCamera;
      }SCRIPT;
   
   SCRIPT script[50];

     char ETGAFileName[]="etgatemp.etga";


   NoAlpha=0;
   if(argc!=2)
   {
      printf("Usage:makeframes stk.cfg\n");
      exit(1);
      }

   fp=fopen(argv[1],"r");
   if(fp==NULL) 
   {
      printf("\n Open stk configure File Error\n");
      exit(1);
      }
   i=0;
   while(fgets(str[i],50,fp)!=NULL)
   {
     t1=strtok(str[i],"\n");
     strcpy(str[i], t1);
     i++;
     }
/* for(;;)
   {
      if(fscanf(fp,"%s\n", str[i])!=EOF)
      {
         if(strcmp(str[i], "VIEWPOINTS")==0) j=i;
         i++;
         }
       else break;
       }
*/
   CFGLineNumber=i;

for(i=0;i<CFGLineNumber;i++)
	printf("%s", str[i]);

   fclose(fp);


/*==========================reading cel names====================*/

	t1=strtok(str[0],"=");
	t1=strtok(NULL,"=");
	j=0;
	for(t2=strtok(t1,",");t2!=NULL;t2=strtok(NULL,","))
	{
		strcpy(celName[j], t2);
		
		j++;
		}
      celNumber=j;


/*==========================end of reading cel names==========*/
/*==========================reading camera====================*/
   
   i=1;
   cameraNumber=0;
   for(;;)
   {
      t1=strtok(str[i]," ");
      t1=strtok(NULL," ");
      camera[cameraNumber].name=t1;
      i++;
      i++;
      /*=======================reading position======================*/
      j=0;
      t1=strtok(str[i],"=");
      t1=strtok(NULL,"=");      	
      for(t2=strtok(t1,",");t2!=NULL;t2=strtok(NULL,","))
      {
	  tmp[j]=atof(t2);
          j++;          
          }
       camera[cameraNumber].position.x=tmp[0];
       camera[cameraNumber].position.y=tmp[1];
       camera[cameraNumber].position.z=-tmp[2];
       

      /*===================end of reading position======================*/
      /*=======================reading viewing direction======================*/
       i++;
       j=0;
       t1=strtok(str[i],"=");
       t1=strtok(NULL,"=");
       for(t2=strtok(t1,",");t2!=NULL;t2=strtok(NULL,","))
       {
	  tmp[j]=atof(t2);
          j++;          
          }
       camera[cameraNumber].direction.x=tmp[0];
       camera[cameraNumber].direction.y=tmp[1];
       camera[cameraNumber].direction.z=-tmp[2];

	
       /*=======================end of reading viewing direction======================*/ 

       /*==================reading up===================*/
       i++;
       t1=strtok(str[i],"=");
       t1=strtok(NULL,"=");       
       camera[cameraNumber].up=atof(t1);
       /*========end of reading up================*/
       i++;
       t1=strtok(str[i],"=");
       t1=strtok(NULL,"=");       
       camera[cameraNumber].zoom=atof(t1);
       i++;
       i++;
       cameraNumber++;
       if(strncmp(str[i], "SCRIPT", 6)==0) break;
       }
/*==========================end of reading camera====================*/

/*============================reading SCRIPT=========================*/
   i++;
   j=i;
   scriptNumber=0;
   for(i=j;i<CFGLineNumber;i++)
   {
      t1=strtok(str[i]," ");
      t2=t1;
      t1=strtok(NULL," ");
      
      t3=strtok(t2, "~");
      script[scriptNumber].startFrame=atoi(t3);
      t4=strtok(NULL,"~");
      script[scriptNumber].endFrame=atoi(t4);
      if(strchr(t1, '~')==NULL )
      {
         script[scriptNumber].startCamera=t1;
	 script[scriptNumber].endCamera=t1;
         }
      else
      {
         t3=strtok(t1, "~");
         script[scriptNumber].startCamera=t3;
	 /* script[scriptNumber].startCamera=strncat(script[scriptNumber].startCamera, "\n",2);*/
         t4=strtok(NULL,"~");
         script[scriptNumber].endCamera=t4;       
         }
      scriptNumber++;
      
      }

/*========================end of reading SCRIPT======================*/

/*******************Reading Parameters*/
   for(i=0;i<celNumber;i++)
	printf("%s\n", celName[i]);
   for(i=0;i<cameraNumber;i++)
   {
      printf("%s\n", camera[i].name);
      printf("%lg,%lg,%lg\n", camera[i].position.x,camera[i].position.y,camera[i].position.z);
      
      printf("%lg,%lg,%lg\n", camera[i].direction.x,camera[i].direction.y,camera[i].direction.z);

      printf("%lg\n", camera[i].zoom);
      }
 
   for(i=0;i<scriptNumber;i++)
   {
      printf("%d~%d,",script[i].startFrame,script[i].endFrame);
      printf("%s~%s\n",script[i].startCamera,script[i].endCamera);
      }

     if(strcmp(script[0].startCamera, camera[0].name)==0) printf("Ok1");
       if(strcmp(script[0].endCamera, camera[1].name)==0) printf("Ok2");

   if(strcmp(script[0].startCamera, "c1")==0) printf("Ok3");
   if(strcmp(script[0].endCamera, "c2")==0) printf("Ok4");

   if(strcmp(camera[0].name, "c1")==0) printf("Ok5");
   if(strcmp(camera[1].name, "c2")==0) printf("Ok6");

 /**************************end of parameters********/


 /*printf("scriptNumber=%d,cameraNumber=%d\n",scriptNumber, cameraNumber);*/


  /*
   celNumber=j-1;
   stkFileNumber=(i-j)/2;
   */



  
      /*strcpy(celName[i],str[i+1]);
      celRotationX[i]=0;
      celRotationY[i]=0;
      celRotationZ[i]=0;
      celTranslationX[i]=0;
      celTranslationY[i]=0;
      celTranslationY[i]=0;
      }*/


 /*   ir_matrix_Construct4(IR_IDENTITY, 0.0, 0.0, 0.0, celTransform);
      printf("\n%d", stkFileNumber);*/
   /*   exit(0);*/
for(j=0;j<scriptNumber;j++)
{   
frameNumber=script[j].endFrame-script[j].startFrame+1;
 printf("frameNumber=%d\n",frameNumber);
for(i=0;i<cameraNumber;i++)
{
if(strcmp(script[j].startCamera, camera[i].name)==0)
{start.name=camera[i].name;
start.position.x=camera[i].position.x;
start.position.y=camera[i].position.y;
start.position.z=camera[i].position.z;
start.direction.x=camera[i].direction.x;
start.direction.y=camera[i].direction.y;
start.direction.z=camera[i].direction.z;
start.up=camera[i].up;
start.zoom=camera[i].zoom;
}
if(strcmp(script[j].endCamera, camera[i].name)==0)
{end.name=camera[i].name;
end.position.x=camera[i].position.x;
end.position.y=camera[i].position.y;
end.position.z=camera[i].position.z;
end.direction.x=camera[i].direction.x;
end.direction.y=camera[i].direction.y;
end.direction.z=camera[i].direction.z;
end.up=camera[i].up;
end.zoom=camera[i].zoom;
}
}

printf("start.position.x=%lg, end.position.x=%lg\n",start.position.x, end.position.x);
printf("start.position.y=%lg, end.position.y=%lg\n",start.position.y, end.position.y);
printf("start.position.z=%lg, end.position.z=%lg\n",start.position.z, end.position.z);
printf("start.direction.x=%lg, end.direction.x=%lg\n",start.direction.x, end.direction.x);
printf("start.direction.y=%lg, end.direction.y=%lg\n",start.direction.y, end.direction.y);
printf("start.direction.z=%lg, end.direction.z=%lg\n",start.direction.z, end.direction.z);
printf("start.up=%lg, end.up=%lg\n",start.up, end.up);
printf("start.zoom=%lg, end.zoom=%lg\n",start.zoom, end.zoom);
/*
if(sqrt(start.direction.y*start.direction.y+start.direction.z*start.direction.z)!=0) temp1=acos(-start.direction.z/sqrt(start.direction.y*start.direction.y+start.direction.z*start.direction.z));
else
temp1=-atan2(start.direction.y,start.direction.z);
if(sqrt(end.direction.y*end.direction.y+end.direction.z*end.direction.z)!=0)
temp2=acos(-end.direction.z/sqrt(end.direction.y*end.direction.y+end.direction.z*end.direction.z));
else
temp2=-atan2(end.direction.y,end.direction.z);
if(sqrt(start.direction.x*start.direction.x+start.direction.z*start.direction.z)!=0)
temp3=-acos(-start.direction.z/sqrt(start.direction.x*start.direction.x+start.direction.z*start.direction.z));
else
temp3=atan2(start.direction.x,start.direction.z);
if(sqrt(end.direction.x*end.direction.x+end.direction.z*end.direction.z)!=0)
temp4=-acos(-end.direction.z/sqrt(end.direction.x*end.direction.x+end.direction.z*end.direction.z));
else
temp4=atan2(end.direction.x,end.direction.z);
total1=temp2-temp1;
total2=temp4-temp3;*/

if((start.direction.y!=0)&&(start.direction.z!=0)) 
{
  if(start.direction.y>0)
temp1=acos(-start.direction.z/sqrt(start.direction.y*start.direction.y+start.direction.z*start.direction.z));
  if(start.direction.y<0)
temp1=-acos(-start.direction.z/sqrt(start.direction.y*start.direction.y+start.direction.z*start.direction.z));
}
else if(start.direction.y==0)
{
  /* if(start.direction.z<=0)*/
temp1=0;
/* else temp1=3.1415926;*/}
else
{
  if(start.direction.y>0)
    temp1=3.1415926/2;
  else temp1=-3.1415926/2;
}

if((end.direction.y!=0)&&(end.direction.z!=0)) 
{
  if(end.direction.y>0)
temp2=acos(-end.direction.z/sqrt(end.direction.y*end.direction.y+end.direction.z*end.direction.z));
  if(end.direction.y<0)
temp2=-acos(-end.direction.z/sqrt(end.direction.y*end.direction.y+end.direction.z*end.direction.z));
}
else if(end.direction.y==0)
{
  /*  if(end.direction.z<=0)*/
temp2=0;
/* else temp2=3.1415926;*/}
else
{
  if(end.direction.y>0)
    temp2=3.1415926/2;
  else temp2=-3.1415926/2;
}

v=sqrt(start.direction.y*start.direction.y+start.direction.z*start.direction.z);
l=sqrt(start.direction.x*start.direction.x+start.direction.y*start.direction.y+start.direction.z*start.direction.z);
if((start.direction.x!=0)&&(v!=0))
{
  if(start.direction.x>0)
    {
      if(start.direction.z>0) temp3=-acos(-v/l);
      else temp3=-acos(v/l);}
  if(start.direction.x<0)
    {
      if(start.direction.z>0) temp3=acos(-v/l);
      else temp3=acos(v/l);}
}
else if(start.direction.x==0)
{
  if(start.direction.z<=0)
temp3=0;
  else temp3=3.1415926;}
else
{
  if(start.direction.x>0)
    temp3=-3.1415926/2;
  else temp3=3.1415926/2;
}
v=sqrt(end.direction.y*end.direction.y+end.direction.z*end.direction.z);
l=sqrt(end.direction.x*end.direction.x+end.direction.y*end.direction.y+end.direction.z*end.direction.z);
printf("v=%lg, l=%lg\n",v,l);
if((end.direction.x!=0)&&(v!=0))
{
  if(end.direction.x>0)
    {
      if(end.direction.z>0) temp4=-acos(-v/l);
      else temp4=-acos(v/l);}
  if(end.direction.x<0)
    {
      if(end.direction.z>0) temp4=acos(-v/l);
      else temp4=acos(v/l);}
}
else if(end.direction.x==0)
{
  if(end.direction.z<=0)
temp4=0;
  else temp4=3.1415926;
}
else
{
  if(end.direction.x>0)
    temp4=-3.1415926/2;
  else temp4=3.1415926/2;
}

/*
if((start.direction.x!=0)&&(start.direction.z!=0))
{
  if(start.direction.x>0)
temp3=-acos(-start.direction.z/sqrt(start.direction.x*start.direction.x+start.direction.z*start.direction.z));
  if(start.direction.x<0)
temp3=acos(-start.direction.z/sqrt(start.direction.x*start.direction.x+start.direction.z*start.direction.z));
}
else if(start.direction.x==0)
{
  if(start.direction.z<=0)
temp3=0;
  else temp3=3.1415926;}
else
{
  if(start.direction.x>0)
    temp3=-3.1415926/2;
  else temp3=3.1415926/2;
}

if((end.direction.x!=0)&&(end.direction.z!=0))
{
  if(end.direction.x>0)
temp4=-acos(-end.direction.z/sqrt(end.direction.x*end.direction.x+end.direction.z*end.direction.z));=
  if(end.direction.x<0)
temp4=acos(-end.direction.z/sqrt(end.direction.x*end.direction.x+end.direction.z*end.direction.z));
}
else if(end.direction.x==0)
{
  if(end.direction.z<=0)
temp4=0;
  else temp4=3.1415926;
}
else
{
  if(end.direction.x>0)
    temp4=-3.1415926/2;
  else temp4=3.1415926/2;
}*/
total1=temp2-temp1;
total2=temp4-temp3;
if(total1==3.1415926) total1=0;
/*if(total2==3.1415926) total2=0;*/
if(total1>3.1415926) total1=total1-2*3.1415926;
if(total1<-3.1415926) total1=2*3.1415926+total1;
if(total2>3.1415926) total2=total2-2*3.1415926;
if(total2<-3.1415926) total2=2*3.1415926+total1;


printf("j=%d\n",j);
printf("startx=%lg\n",temp1);
printf("endx=%lg\n",temp2);
printf("starty=%lg\n",temp3);
printf("endy=%lg\n",temp4);
printf("total1=%lg, total2=%lg\n",total1,total2);
/*
   tempx=end.direction.x-start.direction.x;
   tempy=end.direction.y-start.direction.y;
   tempz=end.direction.z-start.direction.z;
   temp2=currentdz/sqrt(currentdy*currentdy+currentdz*currentdz);
   temp1=currentdz/sqrt(currentdx*currentdx+currentdz*currentdz);
   temp2=currentdz/sqrt(currentdy*currentdy+currentdz*currentdz);*/


    for(k=0;k<frameNumber;k++)
   {

     if(k==0)printf("\nAnother Loop!\n");

     if(j==0)
       {
     currentpx=(end.position.x-start.position.x)*k/(frameNumber-1)+start.position.x;
     currentpy=(end.position.y-start.position.y)*k/(frameNumber-1)+start.position.y;
     currentpz=(end.position.z-start.position.z)*k/(frameNumber-1)+start.position.z;
     current1=total1*k/(frameNumber-1)+temp1;
     current2=total2*k/(frameNumber-1)+temp3;
     /*     currentdx=(end.direction.x-start.direction.x)*k/(frameNumber-1)+start.direction.x;
     currentdy=(end.direction.y-start.direction.y)*k/(frameNumber-1)+start.direction.y;
     currentdz=(end.direction.z-start.direction.z)*k/(frameNumber-1)+start.direction.z;*/
     currentup=(end.up-start.up)*k/(frameNumber-1)+start.up;
     currentzoom=(end.zoom-start.zoom)*k/(frameNumber-1)+start.zoom;
       }
     else
       {
       currentpx=(end.position.x-start.position.x)*(k+1)/frameNumber+start.position.x;
     currentpy=(end.position.y-start.position.y)*(k+1)/frameNumber+start.position.y;
     currentpz=(end.position.z-start.position.z)*(k+1)/frameNumber+start.position.z;
     current1=total1*(k+1)/frameNumber+temp1;
     current2=total2*(k+1)/frameNumber+temp3;
     /*    currentdx=(end.direction.x-start.direction.x)*(k+1)/frameNumber+start.direction.x;
     currentdy=(end.direction.y-start.direction.y)*(k+1)/frameNumber+start.direction.y;
     currentdz=(end.direction.z-start.direction.z)*(k+1)/frameNumber+start.direction.z;*/
     currentup=(end.up-start.up)*(k+1)/frameNumber+start.up;
     currentzoom=(end.zoom-start.zoom)*(k+1)/frameNumber+start.zoom;
       }

     printf("currentpx=%lg,currentpy=%lg,currentpz=%lg\n",currentpx,currentpy,currentpz);
     /*   printf("currentdx=%lg,currentdy=%lg,currentdz=%lg\n",currentdx,currentdy,currentdz);*/
     printf("currentup=%lg\n",currentup);
     printf("currentx=%lg, currenty=%lg\n",current1,current2);
     printf("startzoom=%lg\n",start.zoom);
     printf("endzoom=%lg\n",end.zoom);
     printf("currentzoom=%lg\n",currentzoom);

     stkFile=fopen("stktemp.stk","w");
         if(stkFile==NULL)
      {
          printf("\nwrite file error\n");
          exit(1);
          }
      
 
      stack = ir_stack_Make();

      ir_stack_SetCOP(stack, currentzoom);

     /*** Loading Each Cel and Saving it to a Stack***/

     for(i=0;i<celNumber;i++)
     {
        fp=fopen(celName[i], "r");
        if(fp==NULL)
         {
            printf("\n Open a Cel File:%s Error", celName[i]);
            exit(1);
            }

 
        if (ir_stkfile_Load(fp)==0) 
        {
           fclose(fp);
           c=ir_cel_Make();
           c=ir_stack_GetTopCel(ir_newStack);
           }
        else 
        {
           fprintf(stderr,"show: Error in load file.\n");
           fclose(fp);
           return -1;
           }
        



           ir_cel_GetSpaceTransform(c, celspacetransform[i]);
           ir_cel_GetSpaceTransform(c, celinitialrotation[i]);
           celinitialrotation[i][3][0]=0;
           celinitialrotation[i][3][1]=0;
           celinitialrotation[i][3][2]=0;
      
            

	   /*  temp1=1-ir_cel_GetDepth(c);
	       temp2=ir_cel_GetDepth(c)+1;*/
        /*  printf("temp1=%lg\n", temp1);*/
        /* printf("temp2=%lg\n", temp2);*/
	   /*  ir_matrix_Construct4(IR_TRANSLATE, 0, 0, temp1, translate1);
	       ir_matrix_Construct4(IR_TRANSLATE, 0, 0, temp2, translate2);*/
       



	   /*   celRotationX[i]=-atan2(currentdy, currentdz)*3.1415926/180*(-1);*/
	   /*     celRotationY[i]=currentdy*3.1415926/180*(-1);*/
           /*celRotationZ[i]=currentdz*3.1415926/180*(-1);*/

	   /*   temp1=currentdz/sqrt(currentdx*currentdx+currentdz*currentdz);
		temp2=currentdz/sqrt(currentdy*currentdy+currentdz*currentdz);*/
	   /*   temp3=currentdz/sqrt(currentdx*currentdx+currentdz*currentdz);
		temp4=currentdz/sqrt(currentdy*currentdy+currentdz*currentdz);*/
	   celRotationX[i]=current1*(-1);
	   celRotationY[i]=current2*(-1);
           celRotationZ[i]=currentup*3.1415926/180*(-1);

	   printf("celRotationX[%d]=%lg\n",i,celRotationX[i]);
	   printf("celRotationY[%d]=%lg\n",i,celRotationY[i]);
	   printf("celRotationZ[%d]=%lg\n",i,celRotationZ[i]);
	        
           celTranslationX[i]=cos(-celRotationY[i])*cos(-celRotationZ[i])*(celspacetransform[i][3][0]-currentpx)+(cos(-celRotationX[i])*sin(-celRotationZ[i])+sin(-celRotationX[i])*sin(-celRotationY[i])*cos(-celRotationZ[i]))*(celspacetransform[i][3][1]-currentpy)+(sin(-celRotationX[i])*sin(-celRotationZ[i])-cos(-celRotationX[i])*sin(-celRotationY[i])*cos(-celRotationZ[i]))*(celspacetransform[i][3][2]+ir_cel_GetDepth(c)-currentpz);
           celTranslationY[i]=-cos(-celRotationY[i])*sin(-celRotationZ[i])*(celspacetransform[i][3][0]-currentpx)+(cos(-celRotationX[i])*cos(-celRotationZ[i])-sin(-celRotationX[i])*sin(-celRotationY[i])*sin(-celRotationZ[i]))*(celspacetransform[i][3][1]-currentpy)+(sin(-celRotationX[i])*cos(-celRotationZ[i])+cos(-celRotationX[i])*sin(-celRotationY[i])*sin(-celRotationZ[i]))*(celspacetransform[i][3][2]+ir_cel_GetDepth(c)-currentpz);
           celTranslationZ[i]=sin(-celRotationY[i])*(celspacetransform[i][3][0]-currentpx)-sin(-celRotationX[i])*cos(-celRotationY[i])*(celspacetransform[i][3][1]-currentpy)+cos(-celRotationX[i])*cos(-celRotationY[i])*(celspacetransform[i][3][2]+ir_cel_GetDepth(c)-currentpz)+currentzoom;
	   /*
           celTranslationX[i]=-temp3*cos(-celRotationZ[i])*(celspacetransform[i][3][0]-currentpx)+(-temp4*sin(-celRotationZ[i])+temp2*(-temp1)*cos(-celRotationZ[i]))*(celspacetransform[i][3][1]-currentpy)+(temp2*sin(-celRotationZ[i])+temp4*(-temp1)*cos(-celRotationZ[i]))*(celspacetransform[i][3][2]+ir_cel_GetDepth(c)-currentpz);
           celTranslationY[i]=temp3*sin(-celRotationZ[i])*(celspacetransform[i][3][0]-currentpx)+(-temp4*cos(-celRotationZ[i])-temp2*temp1*sin(-celRotationZ[i]))*(celspacetransform[i][3][1]-currentpy)+(temp2*cos(-celRotationZ[i])-temp4*(-temp1)*sin(-celRotationZ[i]))*(celspacetransform[i][3][2]+ir_cel_GetDepth(c)-currentpz);
           celTranslationZ[i]=-temp1*(celspacetransform[i][3][0]-currentpx)-temp2*(-temp3)*(celspacetransform[i][3][1]-currentpy)+(-temp4)*(-temp3)*(celspacetransform[i][3][2]+ir_cel_GetDepth(c)-currentpz)+currentzoom;*/
          
	   ir_cel_SetDepth(c, 0);
	   /*
	   ir_matrix_Copy4(celRotateX, identity4);
	   ir_matrix_Copy4(celRotateX, identity4);
	   ir_matrix_Copy4(celRotateX, identity4);

	   celRotateX[1][1]=-temp4;
	   celRotateX[1][2]=-temp2;
	   celRotateX[2][1]=temp2;
	   celRotateX[1][1]=-temp4;

	   celRotateY[0][0]=-temp3;
	   celRotateY[0][2]=-temp1;
	   celRotateY[2][0]=temp1;
	   celRotateY[2][2]=-temp3;*/

	   ir_matrix_Construct4(IR_ROTATEX, celRotationX[i], 0.0, 0.0, celRotateX);
	   ir_matrix_Construct4(IR_ROTATEY, celRotationY[i], 0.0, 0.0, celRotateY);
    ir_matrix_Mul4(celRotateX, celRotateY, celRotateY);
    ir_matrix_Construct4(IR_ROTATEZ, celRotationZ[i], 0.0, 0.0, celRotateZ);
    ir_matrix_Mul4(celRotateY, celRotateZ, celRotate);
    ir_matrix_Construct4(IR_TRANSLATE, celTranslationX[i], celTranslationY[i], celTranslationZ[i], celTranslate);
    ir_matrix_Mul4(celRotate, celTranslate, celTransform);
    ir_matrix_Mul4(celinitialrotation[i], celTransform, celTransform);
    /*
    pp=celTransform[1][1];
    printf("\npp=%lf\n", pp);
    */

   ir_cel_Set3DTransform(c, celTransform);

   /*   ir_cel_GetSpaceTransform(c, celspacetransform[i]);*/
   /*printf("\ntemp11=%lf\n", celspacetransform[i][1][1]);*/


   (void)ir_stack_AddCel(stack, c, IR_ADD_ON_TOP, 0);

   /*celTranslationX[i]=celTranslationX[i]-TX;
   celTranslationY[i]=celTranslationY[i]-TY;
   celTranslationZ[i]=celTranslationZ[i]-TZ;*/
   /*printf("ok%d\n", i);*/ 
   
        }

     ir_stack_Save(stack, stkFile);
     fclose(stkFile);
     ir_stack_Delete(stack);

/*** Create image data structure ***/
  iminfo = ir_imageinfo_Make(Width, Height);

  if (StartingLine!=0 || EndingLine!=Height-1)
    ir_imageinfo_SetSELines(iminfo, StartingLine, EndingLine);

  ir_imageinfo_SetAntiAliasing(iminfo,
		    SuperSamplingFactor==1?IR_AA_NONE:IR_AA_SUPERSAMPLING_BOX,
		    SuperSamplingFactor,SuperSamplingFactor);

fp = fopen("stktemp.stk", "r");

  if (fp == NULL) {
    fprintf(stderr,"irend error: Couldn't open file %s.\n", "stktemp.stk");
    return -1;
  }

  /*  if (Verbose) printf("irend: loading stack file.\n");*/
  
  if (ir_stkfile_Load(fp)==0) { 

    fclose(fp);


    ir_display_Open(IR_DISPLAY_ETGA,
		    iminfo,
		    ETGAFileName,
		    (Verbose>=2)?progress:NULL,
		    (Verbose>=1)?message:NULL);

    /*    if (Verbose) printf("irend: rendering stack file.\n");*/

    printf("haze=%lg\n", haze);
    /* exit(1);*/
    ir_render(ir_newStack, iminfo, haze);

    ir_display_Close();

    /*    if (Verbose) message("show: Finished rendering.\n");*/
    
    ir_imageinfo_Delete(iminfo);
  }
  else {
    fprintf(stderr,"show: Error in load file.\n");
    fclose(fp);
    return -1;
  }

  ir_stack_Delete(ir_newStack);
 

  /*  if (argc<3) {
    printf("usage: etga2tga <in_filename> <out_filename> <options>\n");
    printf("       options can be any of:\n");
    printf("       -v: verbose\n");
    printf("       -vv: more verbose\n");
    printf("       -noalpha: do not include an alpha channel in the TGA file\n");
    return -1;
    }*/



  g=k+h;
  strcpy(filename, "frame");
  index=itoa(g);
  strncat(filename,index,strlen(index));
  strncat(filename,".tga",strlen(".tga"));
  /* stkFile=fopen(filename,"w");*/
    
  assert(infile = fopen(ETGAFileName,"r"));
  assert(outfile = fopen(filename,"w"));

  /* for (i=1;i<argc;i++)
    if (!strcmp(argv[i],"-vv")) {
    verbose = 2;
    }
    else if (!strcmp(argv[i],"-v")) {
      verbose = 1;
    }
    else if (!strcmp(argv[i],"-noalpha")) {
      NoAlpha = 1;
      }*/


  fread(header_in, 1, 4, infile);

  header_out[0] = 0; /* no ImageID field */
  header_out[1] = 0; /* no colourmap */
  header_out[2] = 10; /* true colour, encoded */
  header_out[3] = header_out[4] = header_out[5] = header_out[6] = 
    header_out[7] = 0; /* colourmap specification */
  header_out[8] = 0; header_out[9] = 0; /* X origin */
  header_out[10] = 0; header_out[11] = 0; /* Y origin */
  header_out[12] = header_in[0]; header_out[13] = header_in[1]; /* width */
  header_out[14] = header_in[2]; header_out[15] = header_in[3]; /* height */

  /*  if (NoAlpha) {
    header_out[16] = 24; 
    header_out[17] = 32; 
  } else {*/
    header_out[16] = 32; /* pixel depth */
    header_out[17] = 40; /* Image Descriptor */
    /* }*/

  fwrite(header_out, 1, 18, outfile);

  /* read packet header */
  while (fread(packet_in,1,2,infile)==2) {
    /*   if (verbose==2)
	 printf("---next packet---\n");*/
    if (packet_in[0]&128)
      translate_packet(RLE);
    else
      translate_packet(RAW);
  }
  /*  if (verbose) {
    printf("Total read   : %ld pixels\n",total_read);
    printf("Total written: %ld pixels\n",total_written);
    }*/

    fclose(infile);
    fclose(outfile);

    /* exit(0);*/
   }
h=h+k;
}

   printf("\n The Frames Has Been Created Successfully!\n");
   exit(0);

   }



      
 char *itoa(int value)
  {
  int count,                   /* number of characters in string       */
      i,                       /* loop control variable                */
      sign;                    /* determine if the value is negative   */
  char *ptr,                   /* temporary pointer, index into string */
       *string,                /* return value                         */
       *temp;                  /* temporary string array               */

  count = 0;
  if ((sign = value) < 0)      /* assign value to sign, if negative    */
     {                         /* keep track and invert value          */
     value = -value;
     count++;                  /* increment count                      */
     }

  /* allocate INTSIZE plus 2 bytes (sign and NULL)                     */
  temp = (char *) malloc(INTSIZE + 2);
  if (temp == NULL)
     {
     return(NULL);
     }
  memset(temp,'\0', INTSIZE + 2);

  string = (char *) malloc(INTSIZE + 2);
  if (string == NULL)
     {
     return(NULL);
     }
  memset(string,'\0', INTSIZE + 2);
  ptr = string;                /* set temporary ptr to string          */

  /*--------------------------------------------------------------------+
  | NOTE: This process reverses the order of an integer, ie:            |
  |       value = -1234 equates to: char [4321-]                        |
  |       Reorder the values using for {} loop below                    |
  +--------------------------------------------------------------------*/
  do {
     *temp++ = value % 10 + '0';   /* obtain modulus and or with '0'   */
     count++;                      /* increment count, track iterations*/
     }  while (( value /= 10) >0);

  if (sign < 0)                /* add '-' when sign is negative        */
     *temp++ = '-';

  *temp-- = '\0';              /* ensure null terminated and point     */
                               /* to last char in array                */

  /*--------------------------------------------------------------------+
  | reorder the resulting char *string:                                 |
  | temp - points to the last char in the temporary array               |
  | ptr  - points to the first element in the string array              |
  +--------------------------------------------------------------------*/
  for (i = 0; i < count; i++, temp--, ptr++)
     {
     memcpy(ptr,temp,sizeof(char));
     }

  return(string);
  }





