avi24_dll.c

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 2.0 - Modelling, Animation and Rendering Package
00003 Copyright (C) 2000 - 2007 OpenFX Development Team
00004 -- */
00005 
00006 /* FILE AVI24_DLL.C    DLL to build AVI video movie from TEMPORARY files */
00007 
00008 // NOTE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! TO USE the DIRECT SHOW PLAYER
00009 // THE alignment must be default!!!!   Zp2 alignment was used for FLC and
00010 // the old AVI player so if moving back to OLD AVI this needs to be checked.
00011 
00012 #include <stdlib.h>
00013 #include <stdio.h>
00014 #include <windows.h>
00015 
00016 #include "../common/mem.h"
00017 
00018 
00019 #if !__WATCOMC__
00020 #define fflush(a) 0
00021 #endif
00022 
00023 extern int AVIEntryPoint(HINSTANCE hInstance, long first_file, long last_file, char *avi_outname);
00024 
00025 extern void configureAVIfile(HWND, char *, void *);
00026 extern void openAVIfile(char *Name, LPBITMAPINFOHEADER lpbi, int compress, long speed);
00027 extern void appendAVIfile(LPBITMAPINFOHEADER lpbi);
00028 extern void closeAVIfile(void);
00029 
00030 #if __X__MIPS__
00031 BOOL WINAPI _CRT_INIT(HINSTANCE ,DWORD , LPVOID );
00032 #endif
00033 
00034 static HINSTANCE app_handle;
00035 static HWND      g_status_window;
00036 static long      compressbuffer[4096];
00037 static LPSTR     lpBitmapHeader = NULL;
00038 static LPSTR     lpBitmapBits   = NULL;
00039 static long  g_range_l,g_range_f;
00040 static long  g_tzeros;
00041 static long  g_pitch;
00042 static char *g_stem_file;
00043 static long  g_ResolutionX,g_ResolutionY;
00044 
00045 #define GOOD 2
00046 #define ALIGNULONG(i)   ((i+3)/4*4)
00047 
00048 void UnCompressLongLine(long bufsize, long *buffer,
00049                          unsigned long *output);
00050 
00051 // read and decompress code
00052 
00053 void  UnCompressLongLine(long bufsize, long *buffer,unsigned long *output){
00054  long p,k;
00055  long i;
00056  k=0; while(k < bufsize){
00057    p = *buffer++; k++;
00058    if(p < 0)
00059      for(i=0; i<= -p; i++){*output++ = *buffer++; k++;}
00060    else{
00061      for(i=0; i<=  p; i++) *output++ = *buffer;
00062      buffer++; k++;
00063    }
00064  }
00065 }
00066 
00067 // end of read and uncompress code
00068 
00069 static long MakeBitmapStructure(int x_size, int y_size){ // make a suitably sized bitmap framework
00070  long imagesize;
00071  int x4_size;
00072  LPBITMAPINFOHEADER lpbi;
00073 
00074  x4_size = ALIGNULONG(x_size*3);
00075  imagesize = (DWORD)x4_size*(DWORD)y_size;
00076  lpBitmapHeader = (LPSTR)X__Malloc((long)sizeof(BITMAPINFOHEADER)
00077                                 +imagesize);
00078  if(lpBitmapHeader == NULL){
00079    return FALSE;
00080  }
00081  lpbi=(LPBITMAPINFOHEADER)lpBitmapHeader;
00082  lpbi->biSize=sizeof(BITMAPINFOHEADER);
00083  lpbi->biWidth=(DWORD)x_size;
00084  lpbi->biHeight=(DWORD)y_size;
00085  lpbi->biPlanes=1;
00086  lpbi->biBitCount=24;
00087  lpbi->biCompression=BI_RGB;
00088  lpbi->biSizeImage=(DWORD)imagesize;
00089  lpbi->biXPelsPerMeter=0;
00090  lpbi->biYPelsPerMeter=0;
00091  lpbi->biClrUsed=0;
00092  lpbi->biClrImportant=0;
00093  lpBitmapBits=(LPSTR)(lpbi);
00094  lpBitmapBits += (lpbi->biSize);
00095  if(lpBitmapBits == NULL){
00096    return 0;
00097  }
00098  memset(lpBitmapBits,255,imagesize);
00099  return x4_size;
00100 }
00101 
00102 /* range_l is last included frame+1 */
00103 
00104 BYTE *GetNextBitmapFromTemporaryFile(long frame){
00105  char filename[512],speed_string[128],format[64];
00106  long x_x,y_y;
00107  unsigned long val,Nt,RGB[4096];
00108  int i,j;
00109  unsigned char *screen,*lp,R,G,B;
00110  FILE *ipf;
00111  //return (BYTE *)lpBitmapHeader;
00112  sprintf(speed_string,"Building frame %03ld",min(frame,g_range_l));
00113  SendMessage(g_status_window,WM_SETTEXT,0,(LPARAM)speed_string);
00114  sprintf(format,"%s%ld%s","%s%0",g_tzeros,"d.32b");
00115  if(frame < g_range_l)sprintf(filename,format,g_stem_file,frame);
00116  else               sprintf(filename,format,g_stem_file,g_range_f);
00117  if((ipf=fopen(strlwr(filename),"rb")) == NULL){
00118    goto FATALOPEN1;
00119  }
00120  if( fread((char *)&x_x,sizeof(long),1,ipf) != 1 ||
00121      fread((char *)&y_y,sizeof(long),1,ipf) != 1)goto FATALREAD;
00122  if(x_x != g_ResolutionX || y_y != g_ResolutionY)goto FATALREAD;
00123  screen=(unsigned char *)lpBitmapBits + g_pitch*(g_ResolutionY - 1); 
00124  for (i = 0; i < g_ResolutionY; i++) {
00125    if(fread((char *)&Nt,sizeof(long),1,ipf) != 1)goto FATALREAD;
00126    if(Nt == 0){
00127      if(fread((char *)RGB,sizeof(unsigned long),g_ResolutionX,ipf)
00128         != g_ResolutionX)goto FATALREAD;
00129    }
00130    else{
00131      if(fread((char *)compressbuffer,sizeof(long),Nt,ipf) != Nt)
00132        goto FATALREAD;
00133      UnCompressLongLine(Nt,compressbuffer,RGB);
00134    }
00135    lp=screen;
00136    for (j = 0; j < g_ResolutionX; j++) {
00137       val=RGB[j];
00138       R = (unsigned char)((val & 0x00ff0000) >> 16);
00139       G = (unsigned char)((val & 0x0000ff00) >>  8);
00140       B = (unsigned char)((val & 0x000000ff));
00141       *lp++ = B; *lp++ = G; *lp++ = R;
00142    }
00143    screen -= g_pitch;
00144  }
00145  fclose(ipf);
00146  //memset(lpBitmapBits,255-frame*10,g_ResolutionX*g_ResolutionY*3);
00147  //{ char ttt[255]; sprintf(ttt,"Load Frame %ld from File [%s] (%ld,%ld)- Pitch=%ld",frame,filename,g_ResolutionX,g_ResolutionY,g_pitch); MessageBox(NULL,ttt,"Load",MB_OK);}
00148  goto XXIT;
00149  FATALREAD:
00150    MessageBox(GetFocus(),(LPCTSTR)"Read failed on temporary file",(LPCTSTR)"Error",MB_OK|MB_TASKMODAL);
00151    fclose(ipf); goto XXIT;
00152  FATALOPEN1:
00153    MessageBox(GetFocus(),(LPCTSTR)"Temporary file open failed",(LPCTSTR)"Error",MB_OK|MB_TASKMODAL);
00154    goto XXIT;
00155  XXIT:
00156  return (BYTE *)lpBitmapHeader;
00157 }
00158 
00159 int _BuildAvi
00160   (HWND parent_window, HWND status_window,
00161    int range_f, int range_l, char *flic_file,
00162    char *stem_file,
00163    int ResolutionX,int ResolutionY,
00164    int nCOLOUR, long speed, long tzeros,
00165    unsigned long *cstats0,unsigned short *cstats1){
00166  char filename[512],format[64];
00167  long pitch,rval;
00168  int i;
00169  if(strrchr(flic_file,'.') != NULL)*strrchr(flic_file,'.')='\0';
00170  strcat(flic_file,".avi");
00171  g_status_window=status_window;
00172  g_tzeros=tzeros;
00173  g_stem_file=stem_file;
00174  g_ResolutionX = ResolutionX; g_ResolutionY = ResolutionY;
00175 #if 0
00176  {
00177   char str[128];
00178   sprintf(str,"AVI-24: Stem=[%s]",stem_file);
00179   MessageBox(GetFocus(),(LPCTSTR)str,(LPCTSTR)"New Flic",MB_OK|MB_TASKMODAL);
00180   sprintf(str,"flic=[%s] ff=%ld lf=%ld",flic_file,range_f,range_l);
00181   MessageBox(GetFocus(),(LPCTSTR)str,(LPCTSTR)"New Flic",MB_OK|MB_TASKMODAL);
00182   sprintf(str,"x=%ld y=%ld speed=%ld",ResolutionX,ResolutionY,speed);
00183   MessageBox(GetFocus(),(LPCTSTR)str,(LPCTSTR)"New Flic",MB_OK|MB_TASKMODAL);
00184  }
00185 #endif
00186  if((range_l - range_f) < 3)return 0;  /* don't animate < 3 frames */
00187 
00188  if((pitch=MakeBitmapStructure(ResolutionX,ResolutionY)) == 0){
00189    MessageBox(GetFocus(),(LPCTSTR)"Out of memory",(LPCTSTR)"AVI24",MB_OK|MB_TASKMODAL);
00190    return 0;
00191  }
00192  g_pitch=pitch; g_range_l=range_l; g_range_f=range_f;
00193  // start the rendering process - wait in loop until finished.
00194  rval=AVIEntryPoint(app_handle, range_f,range_l, flic_file);
00195  //
00196  if(MessageBox(GetFocus(),(LPCTSTR)"Delete Temporary files",
00197           (LPCTSTR)"Flic",MB_YESNO|MB_TASKMODAL|MB_ICONQUESTION) == IDYES){
00198    FILE *FF;
00199    sprintf(format,"%s%ld%s","%s%0",tzeros,"d.32b");
00200    sprintf(filename,format,stem_file,range_f);
00201    if((FF=fopen(filename,"r")) != NULL){
00202      fclose(FF);
00203      for(i=range_f;i<range_l;i++){
00204        sprintf(format,"%s%ld%s","%s%0",tzeros,"d.32b");
00205        sprintf(filename,format,stem_file,i);
00206        if(DeleteFile(filename) == FALSE){
00207          MessageBox(GetFocus(),(LPCTSTR)strcat(filename," Failed during delete"),
00208          (LPCTSTR)"Flic",MB_OK|MB_TASKMODAL);
00209          break;
00210        }
00211      }
00212    }
00213    else MessageBox(GetFocus(),(LPCTSTR)"Failed to delete temporary files",
00214           (LPCTSTR)"Flic",MB_OK|MB_TASKMODAL);
00215  }
00216  if(lpBitmapHeader != NULL)X__Free(lpBitmapHeader);
00217  return rval; 
00218 }
00219 
00221 
00222 int _BuildAviOld
00223   (HWND parent_window, HWND status_window,
00224    int range_f, int range_l, char *flic_file,
00225    char *stem_file,
00226    int ResolutionX,int ResolutionY,
00227    int nCOLOUR, long speed, long tzeros,
00228    unsigned long *cstats0,unsigned short *cstats1){
00229  char filename[512],speed_string[128],format[64];
00230  long x_x,y_y;
00231  unsigned long val,Nt,RGB[4096];
00232  int i,j,frame,pitch;
00233  unsigned char *screen,*lp,R,G,B;
00234  FILE *ipf;
00235  if(strrchr(flic_file,'.') != NULL)*strrchr(flic_file,'.')='\0';
00236  strcat(flic_file,".avi");
00237 #if 0
00238  {
00239   char str[128];
00240   sprintf(str,"AVI-24: Stem=[%s]",stem_file);
00241   MessageBox(GetFocus(),(LPCTSTR)str,(LPCTSTR)"Flic",MB_OK|MB_TASKMODAL);
00242   sprintf(str,"flic=[%s] ff=%ld lf=%ld",flic_file,range_f,range_l);
00243   MessageBox(GetFocus(),(LPCTSTR)str,(LPCTSTR)"Flic",MB_OK|MB_TASKMODAL);
00244   sprintf(str,"x=%ld y=%ld speed=%ld",ResolutionX,ResolutionY,speed);
00245   MessageBox(GetFocus(),(LPCTSTR)str,(LPCTSTR)"Flic",MB_OK|MB_TASKMODAL);
00246  }
00247 #endif
00248  if((range_l - range_f) < 3)return 0;  /* don't animate < 3 frames */
00249  // Palette not needed for AVI use this if we wish to compress the movie.
00250  if(nCOLOUR == 1)configureAVIfile(parent_window,NULL,NULL);
00251  if(speed < 0)speed=5;
00252  if((pitch=MakeBitmapStructure(ResolutionX,ResolutionY)) == 0){
00253    MessageBox(GetFocus(),(LPCTSTR)"Out of memory",(LPCTSTR)"AVI24",MB_OK|MB_TASKMODAL);
00254    return 0;
00255  }
00256  g_pitch=pitch; 
00257  for(frame=range_f;frame<=range_l;frame++){
00258    sprintf(speed_string,"Building frame %03ld",min(frame,range_l));
00259    SendMessage(status_window,WM_SETTEXT,0,(LPARAM)speed_string);
00260    sprintf(format,"%s%ld%s","%s%0",tzeros,"d.32b");
00261    if(frame < range_l)sprintf(filename,format,stem_file,frame);
00262    else               sprintf(filename,format,stem_file,range_f);
00263    if((ipf=fopen(strlwr(filename),"rb")) == NULL){
00264      goto FATALOPEN1;
00265    }
00266    if( fread((char *)&x_x,sizeof(long),1,ipf) != 1 ||
00267        fread((char *)&y_y,sizeof(long),1,ipf) != 1)goto FATALREAD;
00268    if(x_x != ResolutionX || y_y != ResolutionY)goto FATALREAD;
00269    screen=(unsigned char *)lpBitmapBits + pitch*(ResolutionY - 1); 
00270    for (i = 0; i < ResolutionY; i++) {
00271      if(fread((char *)&Nt,sizeof(long),1,ipf) != 1)goto FATALREAD;
00272      if(Nt == 0){
00273        if(fread((char *)RGB,sizeof(unsigned long),ResolutionX,ipf)
00274           != ResolutionX)goto FATALREAD;
00275      }
00276      else{
00277        if(fread((char *)compressbuffer,sizeof(long),Nt,ipf) != Nt)
00278          goto FATALREAD;
00279        UnCompressLongLine(Nt,compressbuffer,RGB);
00280      }
00281      lp=screen;
00282      for (j = 0; j < ResolutionX; j++) {
00283         val=RGB[j];
00284         R = (unsigned char)((val & 0x00ff0000) >> 16);
00285         G = (unsigned char)((val & 0x0000ff00) >>  8);
00286         B = (unsigned char)((val & 0x000000ff));
00287         *lp++ = B; *lp++ = G; *lp++ = R;
00288      }
00289      screen -= pitch;
00290    }
00291    fclose(ipf);
00292  
00293    if(frame == range_f){
00294      //openAVIfile(flic_file,(LPBITMAPINFOHEADER)lpBitmapHeader,1,25);
00295      openAVIfile(flic_file,(LPBITMAPINFOHEADER)lpBitmapHeader,0,25);
00296      appendAVIfile((LPBITMAPINFOHEADER)lpBitmapHeader);
00297    }
00298    else if(frame == range_l){
00299      closeAVIfile();
00300    }
00301    else{
00302      appendAVIfile((LPBITMAPINFOHEADER)lpBitmapHeader);
00303      Sleep(0);
00304    }
00305  }
00306 
00307  if(MessageBox(GetFocus(),(LPCTSTR)"Delete Temporary files",
00308           (LPCTSTR)"Flic",MB_YESNO|MB_TASKMODAL|MB_ICONQUESTION) == IDYES){
00309    FILE *FF;
00310    sprintf(format,"%s%ld%s","%s%0",tzeros,"d.32b");
00311    sprintf(filename,format,stem_file,range_f);
00312    if((FF=fopen(filename,"r")) != NULL){
00313      fclose(FF);
00314      for(i=range_f;i<range_l;i++){
00315        sprintf(format,"%s%ld%s","%s%0",tzeros,"d.32b");
00316        sprintf(filename,format,stem_file,i);
00317        if(DeleteFile(filename) == FALSE){
00318          MessageBox(GetFocus(),(LPCTSTR)strcat(filename," Failed during delete"),
00319          (LPCTSTR)"Flic",MB_OK|MB_TASKMODAL);
00320          break;
00321        }
00322      }
00323    }
00324    else MessageBox(GetFocus(),(LPCTSTR)"Failed to delete temporary files",
00325           (LPCTSTR)"Flic",MB_OK|MB_TASKMODAL);
00326  }
00327  goto XXIT;
00328  FATALREAD:
00329    MessageBox(GetFocus(),(LPCTSTR)"Read failed on temporary file",(LPCTSTR)"Error",MB_OK|MB_TASKMODAL);
00330    fclose(ipf); goto XXIT;
00331  FATALOPEN1:
00332    MessageBox(GetFocus(),(LPCTSTR)"Temporary file open failed",(LPCTSTR)"Error",MB_OK|MB_TASKMODAL);
00333    goto XXIT;
00334  XXIT:
00335  if(lpBitmapHeader != NULL)X__Free(lpBitmapHeader);
00336  return 1;
00337 }
00338 
00339 
00340 /************************** DLL entry point ********************************/
00341 
00342 #if __WATCOMC__
00343 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00344 #else
00345 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00346 #endif
00347   switch (dwReason) {
00348     case DLL_PROCESS_ATTACH: {
00349 #if __X__MIPS__
00350       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00351 #endif
00352       app_handle = hDLL; 
00353 //      MessageBox (GetFocus(),"AVI builder attaching","Debug",MB_OK);
00354       break;
00355     }
00356     case DLL_PROCESS_DETACH:
00357 #if __X__MIPS__
00358       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00359 #endif
00360 //      MessageBox (GetFocus(),"AVI builder detaching","Debug",MB_OK);
00361       break;
00362   }
00363   return (int)TRUE;
00364 }
00365 
00366 #if __SC__
00367 #pragma startaddress(DllMain)
00368 #endif
00369 

Generated on Sun Apr 27 14:20:13 2014 for OpenFX by  doxygen 1.5.6