GIF_DLL.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 1.0 - Modelling, Animation and Rendering Package
00003 Copyright (C) 2000 OpenFX Development Team
00004 
00005 This program is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 
00019 You may contact the OpenFX development team via elecronic mail
00020 at core@openfx.org, or visit our website at http://openfx.org for
00021 further information and support details.
00022 -- */
00023 
00024 /* FILE GIF_DLL.C    Build animating GIF from TEMPORARY files */
00025 
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <windows.h>
00029 
00030 #include "giflib.h"
00031 
00032 #ifdef __X__NT__
00033 #define X__Malloc(s)    LocalAlloc(LMEM_FIXED,s)
00034 #define X__Free(p)      LocalFree((HLOCAL)p)
00035 #define X__Realloc(p,s) LocalReAlloc((HLOCAL)p,s,LMEM_MOVEABLE)
00036 #else
00037 #define X__Malloc(s)    GlobalAlloc(GMEM_FIXED,s)
00038 #define X__Free(p)      GlobalFree((HGLOBAL)p)
00039 #define X__Realloc(p,s) GlobalReAlloc((HGLOBAL)p,s,GMEM_MOVEABLE)
00040 #endif
00041 
00042 #if __X__MIPS__
00043 BOOL WINAPI _CRT_INIT(HINSTANCE ,DWORD , LPVOID );
00044 #endif
00045 
00046 #define GOOD 2
00047 #define GIFCOLOURS 256
00048 
00049 static unsigned long   *colorstats0;
00050 static unsigned short  *colorstats1;
00051 
00052 extern long getcolor(unsigned short crgb, long Npalette);
00053 extern void SortColours(long Ngif, long N_colours);
00054 extern void UnCompressWordLine(short bufsize, short *buffer,
00055                                unsigned short *output);
00056 
00057 static short compressbuffer[1024];
00058 GifColorType GifColourMap[GIFCOLOURS];
00059 GifFileType *GifFile;
00060 unsigned char *decoderline;
00061 
00062 // read and decompress code
00063 
00064 #ifdef _SUNSTYLE
00065 void  UnCompressWordLine(bufsize,buffer,output)
00066 short bufsize;short *buffer; unsigned short *output;{
00067 #else
00068 void  UnCompressWordLine(short bufsize, short *buffer,unsigned short *output){
00069 #endif
00070  short p,k;
00071  long i;
00072  k=0; while(k < bufsize){
00073    p = *buffer++; k++;
00074    if(p < 0)
00075      for(i=0; i<= -p; i++){*output++ = *buffer++; k++;}
00076    else{
00077      for(i=0; i<=  p; i++) *output++ = *buffer;
00078      buffer++; k++;
00079    }
00080  }
00081 }
00082 
00083 #ifdef _SUNSTYLE
00084 static long distance(argb,brgb) unsigned short argb; unsigned short brgb; {
00085 #else
00086 static long distance(unsigned short argb, unsigned short brgb){
00087 #endif
00088     long b,g,r;
00089     b  = (long)( argb        & 0x1f);
00090     g  = (long)((argb >>  5) & 0x1f);
00091     r  = (long)((argb >> 10) & 0x1f);
00092     b -= (long)( brgb        & 0x1f);
00093     g -= (long)((brgb >>  5) & 0x1f);
00094     r -= (long)((brgb >> 10) & 0x1f);
00095     return (r*r + g*g + b*b);
00096 /*    return labs(r) + labs(g) + labs(b);
00097 */
00098 }
00099 
00100 #ifdef _SUNSTYLE
00101 long getcolor(crgb, Npalette) unsigned short crgb; long Npalette; {
00102 #else
00103 long getcolor(unsigned short crgb, long Npalette){
00104 #endif
00105   long i,j,best,dist;
00106 /* look for an exact match in the color table (or minimal distance) */
00107     for (i=0; i < Npalette; i++) {
00108        if (colorstats1[i] == crgb) return (i);
00109        if (i == 0) {
00110          best = 0;
00111          dist = distance(colorstats1[i],crgb);
00112        }
00113        else if ((j=distance(colorstats1[i],crgb)) < dist) {
00114          best = i;
00115          dist = j;
00116        }
00117     }
00118     return(best);
00119 }
00120 
00121 #ifdef _SUNSTYLE
00122 void SortColours(Ngif,N_colours) long Ngif; long N_colours; {
00123 #else
00124 void SortColours(long Ngif, long N_colours){
00125 #endif
00126  long i,j,gap,t0,maxdis,used;
00127  unsigned short t1;
00128  for (i = 0; i < N_colours; i++) {
00129      colorstats1[i] = i;
00130  }
00131  for (gap = N_colours/2; gap > 0; gap /=2) {
00132   for (i = gap; i < N_colours; i++) {
00133     for (j = i-gap; j >= 0 &&
00134         colorstats0[j] < colorstats0[j+gap]; j -= gap) {
00135       t0 = colorstats0[j];
00136       t1 = colorstats1[j];
00137       colorstats0[j] = colorstats0[j+gap];
00138       colorstats1[j] = colorstats1[j+gap];
00139       colorstats0[j+gap] = t0;
00140       colorstats1[j+gap] = t1;
00141     }
00142   }
00143  }
00144  for (used = 0; used < N_colours && colorstats0[used] > 0; used++){;}
00145  if (used > Ngif) {
00146   for (maxdis = 2; maxdis < 1024; maxdis *= 2) {
00147    for (i=Ngif/2; i < Ngif; i++) {
00148     for (j = 0; j < i; j++) {
00149       if (distance(colorstats1[i],colorstats1[j])<maxdis) {
00150        for (j=i+1; j< used; j++) {
00151          colorstats0[j-1] = colorstats0[j];
00152          colorstats1[j-1] = colorstats1[j];
00153        }
00154        --used;
00155        --i;
00156        break;
00157       }
00158     }
00159     if (used <= Ngif) break;
00160    }
00161    if (used <= Ngif) break;
00162   }
00163  }
00164  return;
00165 }
00166 
00167 // end of read and uncompress code
00168 
00169 void _BuildGif
00170 (  HWND parent_window, HWND status_window,
00171    int range_f, int range_l, char *flic_file,
00172    char *stem_file,
00173    int ResolutionX,int ResolutionY,
00174    int nCOLOUR, long speed, long tzeros,
00175    unsigned long *cstats0,unsigned short *cstats1){
00176 
00177  char filename[128],speed_string[128],*pp,format[64];
00178  long used,cpix,size,type,x_x,y_y;
00179  unsigned short val,Nt,RGB[1024];
00180  int i,j,frame,frames_found;
00181  unsigned char *Screen1,*screen;
00182  FILE *ipf;
00183  colorstats0=cstats0;
00184  colorstats1=cstats1;
00185  if((range_l - range_f) < 3)return;  /* don't animate < 3 frames */
00186  size=ResolutionX*ResolutionY;
00187  if((Screen1 = (unsigned char *)X__Malloc(size)) == NULL){
00188    MessageBox(GetFocus(),(LPCTSTR)"Out of memory",(LPCTSTR)"Flic",MB_OK|MB_TASKMODAL);
00189    return;
00190  }
00191  memset(Screen1,'0',size);
00192  SendMessage(status_window,WM_SETTEXT,0,(LPARAM)"Building color palette");
00193  SortColours(GIFCOLOURS,nCOLOUR);
00194  for(i=0;i<GIFCOLOURS;i++){
00195    GifColourMap[i].Red   = (((colorstats1[i] >> 10) & 0x1F) << 3);
00196    GifColourMap[i].Green = (((colorstats1[i] >>  5) & 0x1F) << 3);
00197    GifColourMap[i].Blue  = (((colorstats1[i]      ) & 0x1F) << 3);
00198  }
00199  for(i=0;i<nCOLOUR;i++)colorstats0[i] = GIFCOLOURS+1;
00200  for(frame=range_f;frame<=range_l;frame++){
00201    sprintf(speed_string,"Building frame %03ld",min(frame,range_l));
00202    SendMessage(status_window,WM_SETTEXT,0,(LPARAM)speed_string);
00203    sprintf(format,"%s%ld%s","%s%0",tzeros,"d.16b");
00204    if(frame < range_l)sprintf(filename,format,stem_file,frame);
00205    else               sprintf(filename,format,stem_file,range_f);
00206 
00207    if((ipf=fopen(strlwr(filename),"rb")) == NULL){
00208      goto FATALOPEN1;
00209    }
00210    if( fread((char *)&x_x,sizeof(long),1,ipf) != 1 ||
00211        fread((char *)&y_y,sizeof(long),1,ipf) != 1)goto FATALREAD;
00212    if(x_x != ResolutionX || y_y != ResolutionY)goto FATALREAD;
00213    screen=Screen1;
00214    for(i=0;i<ResolutionY;i++){
00215      if(fread((char *)&Nt,sizeof(short),1,ipf) != 1)goto FATALREAD;
00216      if(Nt == 0){
00217        if(fread((char *)RGB,sizeof(unsigned short),ResolutionX,ipf)
00218           != ResolutionX)goto FATALREAD;
00219      }
00220      else{
00221        if(fread((char *)compressbuffer,sizeof(short),Nt,ipf) != Nt)
00222          goto FATALREAD;
00223        UnCompressWordLine(Nt,compressbuffer,RGB);
00224      }
00225      for (j = 0; j < ResolutionX; j++) {
00226        val=RGB[j];
00227        if((cpix = (long)colorstats0[(long)val]) > GIFCOLOURS){
00228          cpix=getcolor(val,GIFCOLOURS);
00229          colorstats0[(long)val]=(unsigned long)cpix;
00230        }
00231        *screen++ = (unsigned char)cpix;
00232      }
00233    }
00234    fclose(ipf);
00235 
00236    if(frame == range_f){  // first frame
00237      if((GifFile=EGifOpenFileName((char *)strlwr(flic_file),FALSE,1)) == NULL)
00238        goto FATALWRITE;
00239      if(EGifPutScreenDesc(GifFile,ResolutionX,ResolutionY,8,
00240         0, 8, GifColourMap) == ERROR)goto FATALWRITE;
00241      if(EGifPutBrowserControlDesc(GifFile,0) == ERROR)goto FATALWRITE;
00242    }
00243    else if(frame == range_l){
00244      if(EGifCloseFile(GifFile) == ERROR) {
00245        goto FATALWRITE;
00246      }
00247    }
00248    if(frame >= range_f && frame < range_l){ /* every image */
00249      if(EGifPutControlDesc(GifFile,1,0,2,0) == ERROR){
00250        goto FATALWRITE;
00251      }
00252      if(EGifPutImageDesc(GifFile,0,0,ResolutionX,ResolutionY,FALSE,1,
00253          NULL) == ERROR){
00254        goto FATALWRITE;
00255      }
00256      for (i=0,screen=Screen1;i<ResolutionY;i++,screen += ResolutionX) {
00257        if (EGifPutLine(GifFile,(PixelType *)screen,ResolutionX) == ERROR) {
00258          goto FATALWRITE;
00259        }
00260      }
00261    }
00262  }
00263  if(MessageBox(GetFocus(),(LPCTSTR)"Delete Temporary files",
00264           (LPCTSTR)"Flic",MB_YESNO|MB_TASKMODAL|MB_ICONQUESTION) == IDYES){
00265    FILE *FF;
00266    sprintf(format,"%s%ld%s","%s%0",tzeros,"d.16b");
00267    sprintf(filename,format,stem_file,range_f);
00268    if((FF=fopen(filename,"r")) != NULL){
00269      fclose(FF);
00270      for(i=range_f;i<range_l;i++){
00271        sprintf(format,"%s%ld%s","%s%0",tzeros,"d.16b");
00272        sprintf(filename,format,stem_file,i);
00273        if(DeleteFile(filename) == FALSE){
00274          MessageBox(GetFocus(),(LPCTSTR)strcat(filename," Failed during delete"),
00275          (LPCTSTR)"Flic",MB_OK|MB_TASKMODAL);
00276          break;
00277        }
00278      }
00279    }
00280    else MessageBox(GetFocus(),(LPCTSTR)"Failed to delete temporary files",
00281           (LPCTSTR)"Flic",MB_OK|MB_TASKMODAL);
00282  }
00283  goto XXIT;
00284  FATALWRITE:
00285    MessageBox(GetFocus(),(LPCTSTR)"Failed on flic write",(LPCTSTR)"Error",MB_OK|MB_TASKMODAL);
00286    fclose(ipf); goto XXIT;
00287  FATALREAD:
00288    MessageBox(GetFocus(),(LPCTSTR)"Read failed on temporary file",(LPCTSTR)"Error",MB_OK|MB_TASKMODAL);
00289    fclose(ipf); goto XXIT;
00290  FATALOPEN1:
00291    MessageBox(GetFocus(),(LPCTSTR)"Temporary file open failed",(LPCTSTR)"Error",MB_OK|MB_TASKMODAL);
00292    goto XXIT;
00293  XXIT:
00294  X__Free(Screen1);
00295 }
00296 
00297 #if __WATCOMC__
00298 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00299 #else
00300 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00301 #endif
00302   switch (dwReason) {
00303     case DLL_PROCESS_ATTACH: {
00304 #if __X__MIPS__
00305       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00306 #endif
00307       break;
00308     }
00309     case DLL_PROCESS_DETACH:
00310 #if __X__MIPS__
00311       if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00312 #endif
00313       break;
00314   }
00315   return (int)TRUE;
00316 }
00317 
00318 #if __SC__
00319 #pragma startaddress(DllMain)
00320 #endif
00321 
00322 
00323 

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