00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <stdlib.h>
00010 #include <stdio.h>
00011 #include <windows.h>
00012
00013 #ifdef __X__NT__
00014 #define X__Malloc(s) LocalAlloc(LMEM_FIXED,s)
00015 #define X__Free(p) LocalFree((HLOCAL)p)
00016 #define X__Realloc(p,s) LocalReAlloc((HLOCAL)p,s,LMEM_MOVEABLE)
00017 #else
00018 #define X__Malloc(s) GlobalAlloc(GMEM_FIXED,s)
00019 #define X__Free(p) GlobalFree((HGLOBAL)p)
00020 #define X__Realloc(p,s) GlobalReAlloc((HGLOBAL)p,s,GMEM_MOVEABLE)
00021 #endif
00022 #if !__WATCOMC__
00023 #define fflush(a) 0
00024 #endif
00025
00026 extern void configureAVIfile(HWND, char *, void *);
00027 extern void openAVIfile(char *Name, LPBITMAPINFOHEADER lpbi, int compress, long speed);
00028 extern void appendAVIfile(LPBITMAPINFOHEADER lpbi);
00029 extern void closeAVIfile(void);
00030
00031 #if __X__MIPS__
00032 BOOL WINAPI _CRT_INIT(HINSTANCE ,DWORD , LPVOID );
00033 #endif
00034
00035 static unsigned long *colorstats0;
00036 static unsigned short *colorstats1;
00037 static short compressbuffer[1024];
00038 static char linebuffer2[1024];
00039 static unsigned char linebuffer[2048];
00040 static unsigned char gif_p_red[256],gif_p_green[256],gif_p_blue[256];
00041 static LPSTR lpBitmapHeader = NULL;
00042 static LPSTR lpBitmapBits = NULL;
00043 static RGBQUAD *pRgb = NULL;
00044 static int x4_size;
00045
00046 #define GOOD 2
00047 #define GIFCOLOURS 256
00048 #define ALIGNULONG(i) ((i+3)/4*4)
00049
00050 long getcolor(unsigned short crgb, long Npalette);
00051 void SortColours(long Ngif, long N_colours);
00052 void UnCompressWordLine(short bufsize, short *buffer,
00053 unsigned short *output);
00054
00055 static void Cshort(unsigned char *c, short v){
00056 unsigned char ch,cl;
00057 ch = (unsigned char)(v >> 8);
00058 cl = (unsigned char)(v & 0x00ff);
00059 *c++ = cl;
00060 *c++ = ch;
00061 }
00062
00063 static void Clong(unsigned char *c, long v){
00064 unsigned char ch,c2,c1,cl;
00065 ch = (unsigned char)((v >> 24) & 0x000000ff);
00066 c2 = (unsigned char)((v >> 16) & 0x000000ff);
00067 c1 = (unsigned char)((v >> 8) & 0x000000ff);
00068 cl = (unsigned char)(v & 0x000000ff);
00069 *c++ = cl;
00070 *c++ = c1;
00071 *c++ = c2;
00072 *c++ = ch;
00073 }
00074
00075 static void Ashort(unsigned char *c,short v){
00076 unsigned char ch,cl;
00077 short ah,al,a;
00078 al = (short)(*c);
00079 ah = (short)(*(c+1));
00080 a = (ah << 8) | al;
00081 a += v;
00082 ch = (unsigned char)(a >> 8);
00083 cl = (unsigned char)(a & 0x00ff);
00084 *c = cl;
00085 *(c+1) = ch;
00086 }
00087
00088 static void Along(unsigned char *c,long v){
00089 unsigned char ch,c2,c1,cl;
00090 long ah,a2,a1,al,a;
00091 al = (long)(*c);
00092 a1 = (long)(*(c+1));
00093 a2 = (long)(*(c+2));
00094 ah = (long)(*(c+3));
00095 a = (ah << 24) | (a2 << 16) | (a1 << 8) | al;
00096 a += v;
00097 ch = (unsigned char)((a >> 24) & 0x000000ff);
00098 c2 = (unsigned char)((a >> 16) & 0x000000ff);
00099 c1 = (unsigned char)((a >> 8) & 0x000000ff);
00100 cl = (unsigned char)(a & 0x000000ff);
00101 *c = cl;
00102 *(c+1) = c1;
00103 *(c+2) = c2;
00104 *(c+3) = ch;
00105 }
00106
00107 static long Tlong(unsigned char *c){
00108 long ah,a2,a1,al,a;
00109 al = (long)(*c);
00110 a1 = (long)(*(c+1));
00111 a2 = (long)(*(c+2));
00112 ah = (long)(*(c+3));
00113 a = (ah << 24) | (a2 << 16) | (a1 << 8) | al;
00114 return a;
00115 }
00116
00117 static short Tshort(unsigned char *c){
00118 short ah,al,a;
00119 al = (short)(*c);
00120 ah = (short)(*(c+1));
00121 a = (ah << 8) | al;
00122 return a;
00123 }
00124
00125
00126
00127 #ifdef _SUNSTYLE
00128 void UnCompressWordLine(bufsize,buffer,output)
00129 short bufsize;short *buffer; unsigned short *output;{
00130 #else
00131 void UnCompressWordLine(short bufsize, short *buffer,unsigned short *output){
00132 #endif
00133 short p,k;
00134 long i;
00135 k=0; while(k < bufsize){
00136 p = *buffer++; k++;
00137 if(p < 0)
00138 for(i=0; i<= -p; i++){*output++ = *buffer++; k++;}
00139 else{
00140 for(i=0; i<= p; i++) *output++ = *buffer;
00141 buffer++; k++;
00142 }
00143 }
00144 }
00145
00146 #ifdef _SUNSTYLE
00147 static long distance(argb,brgb) unsigned short argb; unsigned short brgb; {
00148 #else
00149 static long distance(unsigned short argb, unsigned short brgb){
00150 #endif
00151 long b,g,r;
00152 b = (long)( argb & 0x1f);
00153 g = (long)((argb >> 5) & 0x1f);
00154 r = (long)((argb >> 10) & 0x1f);
00155 b -= (long)( brgb & 0x1f);
00156 g -= (long)((brgb >> 5) & 0x1f);
00157 r -= (long)((brgb >> 10) & 0x1f);
00158 return (r*r + g*g + b*b);
00159
00160
00161 }
00162
00163 #ifdef _SUNSTYLE
00164 long getcolor(crgb, Npalette) unsigned short crgb; long Npalette; {
00165 #else
00166 long getcolor(unsigned short crgb, long Npalette){
00167 #endif
00168 long i,j,best,dist;
00169
00170 for (i=0; i < Npalette; i++) {
00171 if (colorstats1[i] == crgb) return (i);
00172 if (i == 0) {
00173 best = 0;
00174 dist = distance(colorstats1[i],crgb);
00175 }
00176 else if ((j=distance(colorstats1[i],crgb)) < dist) {
00177 best = i;
00178 dist = j;
00179 }
00180 }
00181 return(best);
00182 }
00183
00184 #ifdef _SUNSTYLE
00185 void SortColours(Ngif,N_colours) long Ngif; long N_colours; {
00186 #else
00187 void SortColours(long Ngif, long N_colours){
00188 #endif
00189 long i,j,gap,t0,maxdis,used;
00190 unsigned short t1;
00191 for (i = 0; i < N_colours; i++) {
00192 colorstats1[i] = i;
00193 }
00194 for (gap = N_colours/2; gap > 0; gap /=2) {
00195 for (i = gap; i < N_colours; i++) {
00196 for (j = i-gap; j >= 0 &&
00197 colorstats0[j] < colorstats0[j+gap]; j -= gap) {
00198 t0 = colorstats0[j];
00199 t1 = colorstats1[j];
00200 colorstats0[j] = colorstats0[j+gap];
00201 colorstats1[j] = colorstats1[j+gap];
00202 colorstats0[j+gap] = t0;
00203 colorstats1[j+gap] = t1;
00204 }
00205 }
00206 }
00207 for (used = 0; used < N_colours && colorstats0[used] > 0; used++){;}
00208 if (used > Ngif) {
00209 for (maxdis = 2; maxdis < 1024; maxdis *= 2) {
00210 for (i=Ngif/2; i < Ngif; i++) {
00211 for (j = 0; j < i; j++) {
00212 if (distance(colorstats1[i],colorstats1[j])<maxdis) {
00213 for (j=i+1; j< used; j++) {
00214 colorstats0[j-1] = colorstats0[j];
00215 colorstats1[j-1] = colorstats1[j];
00216 }
00217 --used;
00218 --i;
00219 break;
00220 }
00221 }
00222 if (used <= Ngif) break;
00223 }
00224 if (used <= Ngif) break;
00225 }
00226 }
00227 return;
00228 }
00229
00230
00231
00232 static BOOL MakeBitmapStructure(int x_size, int y_size){
00233 int i;
00234 long imagesize;
00235 LPBITMAPINFOHEADER lpbi;
00236 x4_size = ALIGNULONG(x_size);
00237 imagesize = (DWORD)x4_size*(DWORD)y_size;
00238 lpBitmapHeader = (LPSTR)X__Malloc((long)sizeof(BITMAPINFOHEADER)
00239 +256L*sizeof(RGBQUAD)+imagesize);
00240 if(lpBitmapHeader == NULL){
00241 return FALSE;
00242 }
00243 lpbi=(LPBITMAPINFOHEADER)lpBitmapHeader;
00244 lpbi->biSize=sizeof(BITMAPINFOHEADER);
00245 lpbi->biWidth=(DWORD)x_size;
00246 lpbi->biHeight=(DWORD)y_size;
00247 lpbi->biPlanes=1;
00248 lpbi->biBitCount=8;
00249 lpbi->biCompression=BI_RGB;
00250 lpbi->biSizeImage=(DWORD)imagesize;
00251 lpbi->biXPelsPerMeter=0;
00252 lpbi->biYPelsPerMeter=0;
00253 lpbi->biClrUsed=256;
00254 lpbi->biClrImportant=256;
00255 pRgb=(RGBQUAD *)((LPSTR)lpbi + lpbi->biSize);
00256 for(i=0;i<256;i++){
00257 pRgb[i].rgbRed = gif_p_red[i] << 2;
00258 pRgb[i].rgbGreen = gif_p_green[i] << 2;
00259 pRgb[i].rgbBlue = gif_p_blue[i] << 2;
00260 }
00261 lpBitmapBits=(LPSTR)(lpbi);
00262 lpBitmapBits += (lpbi->biSize+256*sizeof(RGBQUAD));
00263 if(lpBitmapBits == NULL){
00264 return FALSE;
00265 }
00266 memset(lpBitmapBits,0,imagesize);
00267 return TRUE;
00268 }
00269
00270 static void MakeBitmapImage(unsigned char *S,int x, int y){
00271 int i,j;
00272 unsigned char *B,*s;
00273 B=(unsigned char *)lpBitmapBits;
00274 for(i=0;i<y;i++){
00275 s=(S+(y-i-1)*x);
00276 for(j=0;j<x;j++){
00277 *B++ = *s++;
00278 }
00279 }
00280 }
00281
00282
00283
00284 #if __SC__
00285
00286 #else
00287 void _BuildAvi
00288 #endif
00289 (HWND parent_window, HWND status_window,
00290 int range_f, int range_l, char *flic_file,
00291 char *stem_file,
00292 int ResolutionX,int ResolutionY,
00293 int nCOLOUR, long speed, long tzeros,
00294 unsigned long *cstats0,unsigned short *cstats1){
00295 char filename[128],speed_string[128],*pp,format[64];
00296 long used,cpix,size,x_x,y_y;
00297 unsigned short val,Nt,RGB[1024];
00298 int i,j,frame,frames_found;
00299 unsigned char *Screen1,*screen;
00300 FILE *ipf;
00301 colorstats0=cstats0;
00302 colorstats1=cstats1;
00303 if(strrchr(flic_file,'.') != NULL)*strrchr(flic_file,'.')='\0';
00304 strcat(flic_file,".avi");
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 if((range_l - range_f) < 3)return;
00315 size=ResolutionX*ResolutionY;
00316 configureAVIfile(parent_window,NULL,NULL);
00317 if(speed < 0)speed=5;
00318 if((Screen1 = (unsigned char *)X__Malloc(size)) == NULL){
00319 MessageBox(GetFocus(),(LPCTSTR)"Out of memory",(LPCTSTR)"Flic",MB_OK|MB_TASKMODAL);
00320 return;
00321 }
00322 memset(Screen1,'0',size);
00323 SendMessage(status_window,WM_SETTEXT,0,(LPARAM)"Building color palette");
00324 SortColours(GIFCOLOURS,nCOLOUR);
00325
00326 for(i=0;i<GIFCOLOURS;i++){
00327 gif_p_red[i] =(unsigned char)((colorstats1[i] >> 10) & 0x1F) << 1;
00328 gif_p_green[i]=(unsigned char)((colorstats1[i] >> 5) & 0x1F) << 1;
00329 gif_p_blue[i] =(unsigned char)((colorstats1[i] ) & 0x1F) << 1;
00330 }
00331 for(i=0;i<nCOLOUR;i++)colorstats0[i] = GIFCOLOURS+1;
00332 if(!MakeBitmapStructure(ResolutionX,ResolutionY)){
00333 X__Free(Screen1);
00334 MessageBox(GetFocus(),(LPCTSTR)"Out of memory",(LPCTSTR)"Flic",MB_OK|MB_TASKMODAL);
00335 return;
00336 }
00337 for(frame=range_f;frame<=range_l;frame++){
00338 sprintf(speed_string,"Building frame %03ld",min(frame,range_l));
00339 SendMessage(status_window,WM_SETTEXT,0,(LPARAM)speed_string);
00340 sprintf(format,"%s%ld%s","%s%0",tzeros,"d.16b");
00341 if(frame < range_l)sprintf(filename,format,stem_file,frame);
00342 else sprintf(filename,format,stem_file,range_f);
00343 if((ipf=fopen(strlwr(filename),"rb")) == NULL){
00344 goto FATALOPEN1;
00345 }
00346 if( fread((char *)&x_x,sizeof(long),1,ipf) != 1 ||
00347 fread((char *)&y_y,sizeof(long),1,ipf) != 1)goto FATALREAD;
00348 if(x_x != ResolutionX || y_y != ResolutionY)goto FATALREAD;
00349 screen=Screen1;
00350 for (i = 0; i < ResolutionY; i++) {
00351 if(fread((char *)&Nt,sizeof(short),1,ipf) != 1)goto FATALREAD;
00352 if(Nt == 0){
00353 if(fread((char *)RGB,sizeof(unsigned short),ResolutionX,ipf)
00354 != ResolutionX)goto FATALREAD;
00355 }
00356 else{
00357 if(fread((char *)compressbuffer,sizeof(short),Nt,ipf) != Nt)
00358 goto FATALREAD;
00359 UnCompressWordLine(Nt,compressbuffer,RGB);
00360 }
00361 for (j = 0; j < ResolutionX; j++) {
00362 val=RGB[j];
00363 if((cpix = (long)colorstats0[(long)val]) > GIFCOLOURS){
00364 cpix=getcolor(val,GIFCOLOURS);
00365 colorstats0[(long)val]=(unsigned long)cpix;
00366 }
00367 *screen++ = (unsigned char)cpix;
00368 }
00369 }
00370 fclose(ipf);
00371 MakeBitmapImage(Screen1,ResolutionX,ResolutionY);
00372 if(frame == range_f){
00373 openAVIfile(flic_file,(LPBITMAPINFOHEADER)lpBitmapHeader,1,15);
00374 appendAVIfile((LPBITMAPINFOHEADER)lpBitmapHeader);
00375 }
00376 else if(frame == range_l){
00377 closeAVIfile();
00378 }
00379 else{
00380 appendAVIfile((LPBITMAPINFOHEADER)lpBitmapHeader);
00381 }
00382 }
00383 if(MessageBox(GetFocus(),(LPCTSTR)"Delete Temporary files",
00384 (LPCTSTR)"Flic",MB_YESNO|MB_TASKMODAL|MB_ICONQUESTION) == IDYES){
00385 FILE *FF;
00386 sprintf(format,"%s%ld%s","%s%0",tzeros,"d.16b");
00387 sprintf(filename,format,stem_file,range_f);
00388 if((FF=fopen(filename,"r")) != NULL){
00389 fclose(FF);
00390 for(i=range_f;i<range_l;i++){
00391 sprintf(format,"%s%ld%s","%s%0",tzeros,"d.16b");
00392 sprintf(filename,format,stem_file,i);
00393 if(DeleteFile(filename) == FALSE){
00394 MessageBox(GetFocus(),(LPCTSTR)strcat(filename," Failed during delete"),
00395 (LPCTSTR)"Flic",MB_OK|MB_TASKMODAL);
00396 break;
00397 }
00398 }
00399 }
00400 else MessageBox(GetFocus(),(LPCTSTR)"Failed to delete temporary files",
00401 (LPCTSTR)"Flic",MB_OK|MB_TASKMODAL);
00402 }
00403 goto XXIT;
00404 FATALREAD:
00405 MessageBox(GetFocus(),(LPCTSTR)"Read failed on temporary file",(LPCTSTR)"Error",MB_OK|MB_TASKMODAL);
00406 fclose(ipf); goto XXIT;
00407 FATALOPEN1:
00408 MessageBox(GetFocus(),(LPCTSTR)"Temporary file open failed",(LPCTSTR)"Error",MB_OK|MB_TASKMODAL);
00409 goto XXIT;
00410 XXIT:
00411 X__Free(Screen1);
00412 if(lpBitmapHeader != NULL)X__Free(lpBitmapHeader);
00413 }
00414
00415
00416
00417 #if __WATCOMC__
00418 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00419 #else
00420 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00421 #endif
00422 switch (dwReason) {
00423 case DLL_PROCESS_ATTACH: {
00424 #if __X__MIPS__
00425 if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00426 #endif
00427
00428 break;
00429 }
00430 case DLL_PROCESS_DETACH:
00431 #if __X__MIPS__
00432 if(!_CRT_INIT(hDLL,dwReason,lpReserved))return(int)FALSE;
00433 #endif
00434
00435 break;
00436 }
00437 return (int)TRUE;
00438 }
00439
00440 #if __SC__
00441 #pragma startaddress(DllMain)
00442 #endif
00443