00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
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
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
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
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;
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){
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){
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