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 #include <stdlib.h>
00026 #include <stdio.h>
00027 #include <time.h>
00028 #include <ctype.h>
00029 #include <math.h>
00030 #include <errno.h>
00031 #include <unistd.h>
00032 #include <string.h>
00033 #include <sys/types.h>
00034 #include <sys/stat.h>
00035 #include <fcntl.h>
00036 #include <dirent.h>
00037 #include <assert.h>
00038 #include <signal.h>
00039
00040 #include "common.h"
00041
00042
00043 #ifdef USE_GD
00044
00045 #include <gd.h>
00046 #include <gdfontmb.h>
00047 #include <gdfontt.h>
00048
00049 #define XMAX 800
00050 #define Xmargin 100
00051 #define YMAX 600
00052 #define Ymargin 60
00053
00054 #define NHOUR (24)
00055 #define TIME_SEGMENT (86400/NHOUR) // toujours 3600!!!
00056
00057
00058 struct {
00059 int school;
00060 int altnorm;
00061 int reverse;
00062 int yscale;
00063 int day;
00064 int ymax;
00065 int offset;
00066 char title[128];
00067 char outfile[128];
00068 } drawing = { 1, 0, 0, 1, 0, 0, 0, "", "" };
00069
00070 FILE *gdBinFile=NULL;
00071 char gdBinFileName[255];
00072
00073 int32_t Vmax[MAX_CHANNEL], Vmin[MAX_CHANNEL];
00074 int64_t Vavg[MAX_CHANNEL];
00075 double Eavg[MAX_CHANNEL];
00076
00077 int32_t AVmin=(1<<30)-1, AVmax=-(1<<30);
00078
00079 float Nmax=0.0;
00080
00081 int ParseImageOptions(char *cmd)
00082 {
00083 char *s=cmd;
00084 int next,error;
00085 if (*s==0)
00086 {
00087 return(0);
00088 }
00089 if (*s!=',')
00090 {
00091 return(-1);
00092 }
00093 while (*s)
00094 {
00095 s++;
00096 next=0;
00097 error=1;
00098 if (strncmp(s,"s=",2)==0)
00099 {
00100 if (sscanf(s+2,"%d%n",&drawing.school,&next)!=1)
00101 {
00102 break;
00103 }
00104 error=0;
00105 next+=2;
00106 }
00107 if (strncmp(s,"d=",2)==0)
00108 {
00109 if (sscanf(s+2,"%d%n",&drawing.day,&next)!=1)
00110 {
00111 break;
00112 }
00113 error=0;
00114 next+=2;
00115 }
00116 if (strncmp(s,"n=",2)==0)
00117 {
00118 if (sscanf(s+2,"%d%n",&drawing.altnorm,&next)!=1)
00119 {
00120 break;
00121 }
00122 error=0;
00123 next+=2;
00124 }
00125 if (strncmp(s,"r=",2)==0)
00126 {
00127 if (sscanf(s+2,"%d%n",&drawing.reverse,&next)!=1)
00128 {
00129 break;
00130 }
00131 error=0;
00132 next+=2;
00133 }
00134 if (strncmp(s,"o=",2)==0)
00135 {
00136 if (sscanf(s+2,"%d%n",&drawing.offset,&next)!=1)
00137 {
00138 break;
00139 }
00140 error=0;
00141 next+=2;
00142 }
00143 if (strncmp(s,"y=",2)==0)
00144 {
00145 if (sscanf(s+2,"%d%n",&drawing.yscale,&next)!=1)
00146 {
00147 break;
00148 }
00149 error=0;
00150 next+=2;
00151 }
00152 if (strncmp(s,"t=",2)==0)
00153 {
00154 int i=0;
00155 s+=2;
00156 while ((*s!=0)&&(*s!=','))
00157 {
00158 drawing.title[i++]=*s;
00159 s++;
00160 }
00161 drawing.title[i]=0;
00162 error=0;
00163 }
00164 if (strncmp(s,"m=",2)==0)
00165 {
00166 if (sscanf(s+2,"%d%n",&drawing.ymax,&next)!=1)
00167 {
00168 break;
00169 }
00170 error=0;
00171 next+=2;
00172 }
00173 if (strncmp(s,"u=",2)==0)
00174 {
00175 int i=0;
00176 s+=2;
00177 while ((*s!=0)&&(*s!=','))
00178 {
00179 drawing.outfile[i++]=*s;
00180 s++;
00181 }
00182 drawing.outfile[i]=0;
00183 error=0;
00184 }
00185 if (error)
00186 {
00187 PrintError("could not parse image option string\n");
00188 return(-1);
00189 }
00190 s+=next;
00191 }
00192 return(0);
00193 }
00194
00197 FILE* OpenGdBinFile(void)
00198 {
00199 int i;
00200
00201 for (i=0; i<MAX_CHANNEL; i++)
00202 {
00203
00204
00205 if ((HWConfig.srObs[i].npts>0)&&(infoHeader[i].npts==0))
00206 {
00207 InitInfoHeader(i);
00208 }
00209 }
00210 if (gdBinFile==NULL)
00211 {
00212 int fd,i;
00213 strcpy(gdBinFileName,"titanfileXXXXXX");
00214 fd=OpenTempFile(gdBinFileName);
00215 assert((gdBinFile=fdopen(fd,"wb"))!=NULL);
00216 setvbuf(gdBinFile,NULL,_IOFBF,FILE_BUFFER_SIZE);
00217 for (i=0; i<MAX_CHANNEL; i++)
00218 {
00219 Vmax[i]=-(1<<30);
00220 Vmin[i]=(1<<30);
00221 Vavg[i]=0;
00222 Eavg[i]=0.0;
00223 }
00224 }
00225 return(gdBinFile);
00226 }
00227
00229 void AbortGdBinFile(void)
00230 {
00231 if (gdBinFile)
00232 {
00233 fclose(gdBinFile);
00234 gdBinFile=NULL;
00235 }
00236 unlink(gdBinFileName);
00237 }
00238
00241 void AddGifData(int channel)
00242 {
00243 int i;
00244 if (channel>MAX_CHANNEL)
00245 {
00246 PrintError("channel number out of bounds\n");
00247 return;
00248 }
00249 if ((HWConfig.srObs[channel].npts==0)||(HWConfig.srExp[channel].npts==0))
00250 {
00251 return;
00252 }
00253 if (OpenGdBinFile())
00254 {
00255 int end=HWConfig.srObs[channel].npts;
00256 if (end>HWConfig.srExp[channel].npts)
00257 {
00258 end=HWConfig.srExp[channel].npts;
00259 }
00260 for (i=0; i<end; i++)
00261 {
00262 int32_t d=HWConfig.data[channel][i];
00263 Vavg[channel]+=d;
00264 if (drawing.altnorm)
00265 {
00266 int32_t v;
00267 v=d-Vavg[channel]/(1+infoHeader[channel].npts+i);
00268 Eavg[channel]+=(v*v);
00269 }
00270 if (Vmin[channel]>d)
00271 {
00272 Vmin[channel]=d;
00273 }
00274 if (Vmax[channel]<d)
00275 {
00276 Vmax[channel]=d;
00277 }
00278 if (fwrite(&channel,sizeof(int),1,gdBinFile)!=1)
00279 {
00280 PrintError("unable to write to %s: %m\n",
00281 gdBinFileName);
00282 AbortGdBinFile();
00283 exit(0);
00284 }
00285 if (fwrite(&d,4,1, gdBinFile)!=1)
00286 {
00287 PrintError("unable to write to %s: %m\n",
00288 gdBinFileName);
00289 AbortGdBinFile();
00290 exit(0);
00291 }
00292 }
00293 infoHeader[channel].npts+=end;
00294 }
00295 }
00296
00297 void PlotImage(char *fn)
00298 {
00299 FILE *fout=NULL;
00300 char *outFileName=NULL;
00301 int lastX[MAX_CHANNEL],lastY[MAX_CHANNEL];
00302 int lastX24=-1,lastY24=-1;
00303 int ndata[MAX_CHANNEL];
00304 int nChannel=0;
00305 int channelOrder[MAX_CHANNEL];
00306 int order=-1;
00307 double Tmax=-(double)(1<<30), Tmin=4294967295., deltaT=0.;
00308 char tmp[255],tmp2[255];
00309 gdImagePtr im=NULL;
00310 int white,black,grey,i,ch;
00311 int channelColor[3];
00312 int line24Color;
00313 double scaleX,scaleY,deltaY;
00314 double div,subdiv;
00315 int y=YMAX-(drawing.day?1.9:0.9)*Ymargin;
00316 int lastCh=-1,doffset=0;
00317 int initPlot=0;
00318 int styleDotted[2];
00319 int Ncolor=3;
00320 int cnt;
00321
00322 im=NULL;
00323 outFileName=fn;
00324
00325 if (drawing.outfile[0]!=0)
00326
00327 {
00328 FILE *fin;
00329 outFileName=drawing.outfile;
00330
00331
00332 fin=fopen(drawing.outfile,"rb");
00333 if (fin!=NULL)
00334 {
00335 PrintLog("loading %s ... ",drawing.outfile);
00336 im = gdImageCreateFromGif(fin);
00337 fclose(fin);
00338 fprintf(stderr,im?"done\n":"error\n");
00339 }
00340 else
00341 {
00342 PrintLog("could not open %s\n",drawing.outfile);
00343 }
00344 }
00345
00346 else
00347 {
00348
00349 AVmin=(1<<30)-1;
00350 AVmax=-(1<<30);
00351
00352 }
00353
00354 if (im==NULL)
00355
00356 {
00357 PrintLog("init image ...\n");
00358
00359 initPlot=1;
00360 im = gdImageCreate(XMAX, YMAX);
00361
00362 }
00363
00364
00365
00366
00367 if (drawing.reverse)
00368 {
00369 white = gdImageColorResolveAlpha(im, 0, 0, 0, 127);
00370 black = gdImageColorResolve(im, 255, 255, 255);
00371 }
00372 else
00373 {
00374 white = gdImageColorResolveAlpha(im, 255, 255, 255, 127);
00375 black = gdImageColorResolve(im, 0, 0, 0);
00376 }
00377
00378 grey = gdImageColorResolve(im, 200, 200, 200);
00379 if (drawing.school)
00380 {
00381 if (drawing.reverse)
00382 {
00383 channelColor[0] = gdImageColorResolve(im, 0, 255, 255);
00384 channelColor[1] = gdImageColorResolve(im, 255, 255, 0);
00385 channelColor[2] = gdImageColorResolve(im, 255, 0, 255);
00386 line24Color = gdImageColorResolve(im, 192, 192, 192);
00387 }
00388 else
00389 {
00390 channelColor[0] = gdImageColorResolve(im, 255, 0, 0);
00391 channelColor[1] = gdImageColorResolve(im, 0, 0, 255);
00392 channelColor[2] = gdImageColorResolve(im, 0, 255, 0);
00393 line24Color = gdImageColorResolve(im, 128, 128, 128);
00394 }
00395 }
00396 else
00397 {
00398 for (i=0; i<3; i++)
00399 {
00400 if (drawing.reverse)
00401 {
00402 channelColor[i] = gdImageColorResolve(im, 0, 255, 255);
00403 line24Color = gdImageColorResolve(im, 192, 192, 192);
00404 }
00405 else
00406 {
00407 channelColor[i] = gdImageColorResolve(im, 0, 0, 200);
00408 line24Color = gdImageColorResolve(im, 128, 128, 128);
00409 }
00410 }
00411 }
00412 if (drawing.day)
00413 {
00414 Ncolor=2;
00415 if (drawing.reverse)
00416 {
00417 channelColor[0] = gdImageColorResolve(im, 0, 255, 128);
00418 channelColor[1] = gdImageColorResolve(im, 255, 128, 0);
00419 }
00420 else
00421 {
00422 channelColor[0] = gdImageColorResolve(im, 255, 0, 128);
00423 channelColor[1] = gdImageColorResolve(im, 0, 128, 255);
00424 }
00425 }
00426 styleDotted[0] = grey;
00427 styleDotted[1] = gdTransparent;
00428 gdImageSetStyle(im, styleDotted, 2);
00429
00430
00431
00432 for (i=0; i<MAX_CHANNEL; i++)
00433 {
00434 double tt;
00435 channelOrder[i]=0;
00436 lastX[i]=lastY[i]=-1;
00437 if (infoHeader[i].npts>0)
00438 {
00439 nChannel++;
00440 order++;
00441 channelOrder[i]=order;
00442 }
00443 else
00444 {
00445 continue;
00446 }
00447 if (AVmin!=-AVmax)
00448 {
00449 if (drawing.altnorm)
00450 {
00451 if (AVmin>-Eavg[i])
00452 {
00453 AVmin=-Eavg[i];
00454 }
00455 if (AVmax<Eavg[i])
00456 {
00457 AVmax=Eavg[i];
00458 }
00459 }
00460 else
00461 {
00462 if (AVmin>Vmin[i])
00463 {
00464 AVmin=Vmin[i];
00465 }
00466 if (AVmax<Vmax[i])
00467 {
00468 AVmax=Vmax[i];
00469 }
00470 }
00471 }
00472 if (drawing.ymax>0)
00473 {
00474 AVmin=Vmin[i]=-drawing.ymax;
00475 AVmax=Vmax[i]=drawing.ymax;
00476 if (drawing.offset!=0)
00477 {
00478 Vavg[i]=drawing.offset;
00479 }
00480 }
00481 if (Tmin>infoHeader[i].correctedTime)
00482 {
00483 Tmin=infoHeader[i].correctedTime;
00484 }
00485 tt=infoHeader[i].correctedTime+
00486 (double)(infoHeader[i].npts*infoHeader[i].sr.div)/
00487 (double)infoHeader[i].sr.base;
00488 if (Tmax<tt)
00489 {
00490 Tmax=tt;
00491 }
00492 }
00493
00494 if ((drawing.outfile[0]!=0)&&(beginWindow>0))
00495 {
00496 Tmin=(double)beginWindow;
00497 Tmax=(double)endWindow;
00498 Vavg[i]=drawing.offset=0;
00499 deltaT=Tmax-Tmin;
00500 if (AVmin<-AVmax)
00501 {
00502 AVmax=-AVmin;
00503 }
00504 else
00505 {
00506 AVmin=-AVmax;
00507 }
00508 }
00509
00510 if (drawing.day==1)
00511 {
00512 deltaT=TIME_SEGMENT;
00513 Tmin=86400.*floor((Tmin+1.)/86400.);
00514 Tmax=Tmin+86400.;
00515 nChannel=(86400.+1.)/TIME_SEGMENT;
00516 scaleX=(double)(XMAX-Xmargin)/TIME_SEGMENT;
00517 scaleY=(double)(YMAX-3*Ymargin)/((double)nChannel*(double)(AVmax-AVmin));
00518 deltaY=(double)(YMAX-3*Ymargin)/(double)nChannel;
00519 }
00520 else
00521 {
00522 deltaT=Tmax-Tmin;
00523 scaleX=(double)(XMAX-Xmargin)/(deltaT);
00524 scaleY=(double)(YMAX-2*Ymargin)/((double)nChannel*(double)(AVmax-AVmin));
00525 deltaY=(double)(YMAX-2*Ymargin)/(double)nChannel;
00526 }
00527
00528 strcpy(tmp,"1s");
00529 strcpy(tmp2,"");
00530 div=1.;
00531 subdiv=0.1;
00532
00533 if (deltaT>10.)
00534 {
00535 strcpy(tmp,"10s");
00536 strcpy(tmp2,"1s");
00537 div=10.;
00538 subdiv=1.;
00539 }
00540
00541 if (deltaT>30.)
00542 {
00543 strcpy(tmp,"30s");
00544 strcpy(tmp2,"5s");
00545 div=30.;
00546 subdiv=5.;
00547 }
00548
00549 if (deltaT>65.)
00550 {
00551 strcpy(tmp,"1min");
00552 strcpy(tmp2,"10s");
00553 div=60.;
00554 subdiv=10.;
00555 }
00556
00557 if (deltaT>310.)
00558 {
00559 strcpy(tmp,"5min");
00560 strcpy(tmp2,"1min");
00561 div=300.;
00562 subdiv=60.;
00563 }
00564
00565 if (deltaT>620.)
00566 {
00567 strcpy(tmp,"10min");
00568 strcpy(tmp2,"1min");
00569 div=600.;
00570 subdiv=60.;
00571 }
00572
00573 if (deltaT>1900.)
00574 {
00575 strcpy(tmp,"30min");
00576 strcpy(tmp2,"5min");
00577 div=1800.;
00578 subdiv=300.;
00579 }
00580
00581 if (deltaT>3700.)
00582 {
00583 strcpy(tmp,"1h");
00584 strcpy(tmp2,"10min");
00585 div=3600.;
00586 subdiv=600.;
00587 }
00588
00589 if (deltaT>11000.)
00590 {
00591 strcpy(tmp,"3h");
00592 strcpy(tmp2,"30min");
00593 div=10800.;
00594 subdiv=1800.;
00595 }
00596
00597 if (deltaT>44000.)
00598 {
00599 strcpy(tmp,"12h");
00600 strcpy(tmp2,"1h");
00601 div=43200.;
00602 subdiv=3600.;
00603 }
00604
00605 if (deltaT>90000)
00606 {
00607 strcpy(tmp,"24h");
00608 strcpy(tmp2,"2h");
00609 div=86400.;
00610 subdiv=7200.;
00611 }
00612
00613 i=0;
00614 while (Tmin+subdiv*(double)i<Tmax)
00615 {
00616 gdImageLine(im,
00617 Xmargin+subdiv*scaleX*(double)i,Ymargin,
00618 Xmargin+subdiv*scaleX*(double)i,y,
00619 gdStyled);
00620 gdImageLine(im,
00621 Xmargin+subdiv*scaleX*(double)i,y,
00622 Xmargin+subdiv*scaleX*(double)i,y+4,
00623 black);
00624 i++;
00625 }
00626
00627 i=0;
00628 while (Tmin+div*(double)i<Tmax)
00629 {
00630
00631 gdImageLine(im,
00632 Xmargin+div*scaleX*(double)i,Ymargin,
00633 Xmargin+div*scaleX*(double)i,y+5,
00634 gdStyled);
00635
00636 gdImageLine(im,
00637 Xmargin+div*scaleX*(double)i,y,
00638 Xmargin+div*scaleX*(double)i,y+8,
00639 black);
00640 i++;
00641 }
00642 gdImageString(im, gdFontGetMediumBold(),
00643 Xmargin+div*scaleX,y+10,
00644 (unsigned char *)tmp, black);
00645 gdImageString(im, gdFontGetMediumBold(),
00646 Xmargin+subdiv*scaleX,y+10,
00647 (unsigned char *)tmp2, black);
00648
00649
00650 if (drawing.day==1)
00651 {
00652 for (i=0; i<24; i++)
00653 {
00654
00655 gdImageLine(im,
00656 Xmargin+3600.*scaleX*(double)i/(double)NHOUR,y+deltaY*5,
00657 Xmargin+3600.*scaleX*(double)i/(double)NHOUR,y+deltaY*5+5,
00658 black);
00659 if (i%Ncolor==0)
00660 {
00661 sprintf(tmp2,"%dh",i);
00662 gdImageString(im, gdFontGetMediumBold(),
00663 Xmargin+((double)i)*3600.*scaleX/(double)NHOUR,
00664 y+deltaY*5+10,
00665 (unsigned char *)tmp2,black);
00666 }
00667 }
00668 }
00669
00670
00671 if (drawing.day==0)
00672 {
00673 strcpy(tmp,time2str(Tmin));
00674 tmp[23]=0;
00675 gdImageString(im, gdFontGetMediumBold(),
00676 Xmargin+2,YMAX-0.9*Ymargin+25,(unsigned char *)tmp, black);
00677 gdImageLine(im, Xmargin,YMAX-Ymargin+20, Xmargin,YMAX-Ymargin+40, black);
00678 gdImageLine(im, Xmargin,YMAX-Ymargin+20, Xmargin+3,YMAX-Ymargin+23, black);
00679 gdImageLine(im, Xmargin,YMAX-Ymargin+20, Xmargin-3,YMAX-Ymargin+23, black);
00680 }
00681 else
00682 {
00683 strcpy(tmp,time2str(Tmin));
00684 tmp[23]=0;
00685 gdImageString(im, gdFontGetMediumBold(),
00686 Xmargin+2,Ymargin-25,(unsigned char *)tmp, black);
00687 gdImageLine(im, Xmargin,Ymargin-2, Xmargin-3,Ymargin-5, black);
00688 gdImageLine(im, Xmargin,Ymargin-2, Xmargin+3,Ymargin-5, black);
00689 gdImageLine(im, Xmargin,Ymargin-20, Xmargin+0,Ymargin-2, black);
00690 }
00691
00692
00693 gdImageLine(im,Xmargin,y,XMAX,y,black);
00694 gdImageLine(im,Xmargin,y+deltaY*5,XMAX,y+deltaY*5,black);
00695
00696
00697 for (i=0; i<MAX_CHANNEL; i++)
00698 {
00699 ndata[i]=0;
00700 if (drawing.day==0)
00701 {
00702 if (infoHeader[i].npts<=0)
00703 {
00704 continue;
00705 }
00706 }
00707 else
00708 {
00709 if (infoHeader[i].npts>0)
00710 {
00711 int j;
00712 for (j=0; j<MAX_CHANNEL; j++)
00713 {
00714 infoHeader[j].correctedTime=infoHeader[i].correctedTime;
00715 }
00716 }
00717 channelOrder[i]=i;
00718 }
00719 if (initPlot==1)
00720 {
00721 gdImageLine(im,
00722 Xmargin,Ymargin+deltaY*(double)channelOrder[i]+deltaY/2.,
00723 XMAX,Ymargin+deltaY*(double)channelOrder[i]+deltaY/2.,
00724 gdStyled);
00725 }
00726 }
00727
00728
00729 rewind(gdBinFile);
00730 while (!feof(gdBinFile))
00731 {
00732 double Xt,Yt;
00733 int32_t d;
00734 cnt++;
00735 if (fread(&ch,sizeof(int),1,gdBinFile)!=1)
00736 {
00737 break;
00738 }
00739 if (ch>=MAX_CHANNEL)
00740 {
00741 PrintLog("corrupted temp file, aborting\n");
00742 break;
00743 }
00744 if (fread(&d,sizeof(int32_t),1,gdBinFile)!=1)
00745 {
00746 break;
00747 }
00748 #ifdef RENICE
00749 SleepIfArm();
00750 #endif
00751
00752 d-=Vavg[ch];
00753
00754
00755 Xt=infoHeader[ch].correctedTime-Tmin;
00756 Xt+=(double)(ndata[ch]*infoHeader[ch].sr.div)/
00757 (double)infoHeader[ch].sr.base;
00758
00759 if (drawing.day==1)
00760 {
00761 Yt=scaleY*(double)(AVmax-d);
00762
00763 if (lastX24>0)
00764 {
00765 gdImageLine(im,
00766 lastX24,lastY24,
00767 Xmargin+(int)(Xt*scaleX/NHOUR),
00768 Ymargin+deltaY*(NHOUR+2.)+deltaY/2.+3.*Yt-1,
00769 line24Color);
00770 }
00771 lastX24=Xmargin+(int)(Xt*scaleX/NHOUR);
00772 lastY24=Ymargin+deltaY*(NHOUR+2.)+deltaY/2.+3.*Yt-1;
00773 }
00774
00775 ndata[ch]++;
00776
00777 if (drawing.day==1)
00778 {
00779 ch=0;
00780 while ((ch<MAX_CHANNEL-1)&&(Xt-TIME_SEGMENT>0.))
00781 {
00782 ch++;
00783 Xt-=TIME_SEGMENT;
00784 }
00785 if (drawing.outfile[0]==0)
00786 {
00787 if (ch!=lastCh)
00788 {
00789 doffset=d;
00790 }
00791 }
00792 lastCh=ch;
00793 }
00794
00795 Yt=deltaY*(double)channelOrder[ch]+deltaY/2.-scaleY*(double)(d-doffset);
00796 Xt*=scaleX;
00797 if (lastX[ch]>0)
00798 {
00799 gdImageLine(im,
00800 lastX[ch],lastY[ch],
00801 Xmargin+(int)Xt,Ymargin+(int)Yt,
00802 channelColor[channelOrder[ch]%Ncolor]);
00803 }
00804 lastX[ch]=Xmargin+(int)Xt;
00805 lastY[ch]=Ymargin+(int)Yt;
00806 }
00807 if (drawing.day==1)
00808 {
00809 if (drawing.yscale)
00810 {
00811 i=1;
00812 }
00813 else
00814 {
00815 i=0;
00816 }
00817 for (; i<MAX_CHANNEL; i++)
00818 {
00819 sprintf(tmp,"%02d:00",i);
00820 gdImageString(im, gdFontGetMediumBold(), Xmargin/2,
00821 Ymargin+(int)(0.95*deltaY/2.+deltaY*(double)channelOrder[i])-5,
00822 (unsigned char *)tmp, black);
00823 }
00824 }
00825
00826
00827 order=-1;
00828 for (i=0; i<MAX_CHANNEL; i++)
00829 {
00830 if (drawing.day==0)
00831 {
00832 if (infoHeader[i].npts<=0)
00833 {
00834 continue;
00835 }
00836 order=i;
00837 sprintf(tmp,"%s",infoHeader[i].channel);
00838 gdImageString(im, gdFontGetMediumBold(), 2,
00839 Ymargin+(int)(0.95*deltaY/2.+deltaY*(double)channelOrder[i])-10,
00840 (unsigned char *)tmp, black);
00841 if (drawing.school==0)
00842 {
00843 sprintf(tmp,"A=%d",Vmax[i]-Vmin[i]);
00844 gdImageString(im, gdFontGetMediumBold(), 2,
00845 Ymargin+(int)(0.95*deltaY/2.+deltaY*(double)channelOrder[i])+0,
00846 (unsigned char *)tmp, black);
00847 sprintf(tmp,"M=%d",(int32_t)Vavg[i]);
00848 gdImageString(im, gdFontGetMediumBold(), 2,
00849 Ymargin+(int)(0.95*deltaY/2.+deltaY*(double)channelOrder[i])+10,
00850 (unsigned char *)tmp, black);
00851 }
00852 }
00853 if (drawing.yscale)
00854 {
00855 float H=pow(10.,floor(log10((AVmax-AVmin))))/10.;
00856 float ymin,ymax;
00857 int xo;
00858 while (H<0.5*(AVmax-AVmin))
00859 {
00860 H*=2.;
00861 }
00862 ymin=Ymargin+deltaY*((double)channelOrder[i]+0.5)-
00863 scaleY*(double)H/2.;
00864 ymax=Ymargin+deltaY*((double)channelOrder[i]+0.5)+
00865 scaleY*(double)H/2.;
00866 gdImageLine(im,Xmargin-3,ymin,Xmargin-3,ymax,black);
00867 gdImageLine(im,Xmargin-3,ymin,Xmargin-7,ymin,black);
00868 gdImageLine(im,Xmargin-3,ymax,Xmargin-7,ymax,black);
00869
00870
00871
00872 sprintf(tmp,"%.0f",H);
00873 xo=Xmargin-strlen(tmp)*8-5;
00874 gdImageString(im, gdFontGetMediumBold(),
00875 xo, ymin-5, (unsigned char *)tmp,black);
00876 sprintf(tmp,"%.0f",-H);
00877 xo=Xmargin-strlen(tmp)*8-5;
00878 gdImageString(im, gdFontGetMediumBold(),
00879 xo, ymax-8, (unsigned char *)tmp,black);
00880
00881
00882 if (drawing.day==1)
00883 {
00884 ymin=Ymargin+deltaY*(NHOUR+3.5)+deltaY/2.-1-
00885 3.*scaleY*(double)H/2.;
00886 ymax=Ymargin+deltaY*(NHOUR+3.5)+deltaY/2.-1+
00887 3.*scaleY*(double)H/2.;
00888 gdImageLine(im,Xmargin-3,ymin,Xmargin-3,ymax,black);
00889 gdImageLine(im,Xmargin-3,ymin,Xmargin-7,ymin,black);
00890 gdImageLine(im,Xmargin-3,ymax,Xmargin-7,ymax,black);
00891
00892 ymin=Ymargin+deltaY*(NHOUR+3.5)+deltaY/2.-1-3.*deltaY/2;
00893 ymax=Ymargin+deltaY*(NHOUR+3.5)+deltaY/2.-1+3.*deltaY/2;
00894 sprintf(tmp,"%.0f",H);
00895 xo=Xmargin-strlen(tmp)*8-5;
00896 gdImageString(im, gdFontGetMediumBold(),
00897 xo, ymin-3, (unsigned char *)tmp,black);
00898 sprintf(tmp,"%.0f",-H);
00899 xo=Xmargin-strlen(tmp)*8-5;
00900 gdImageString(im, gdFontGetMediumBold(),
00901 xo, ymax-10, (unsigned char *)tmp,black);
00902 }
00903 }
00904 if (drawing.day==1)
00905 {
00906 break;
00907 }
00908 }
00909
00910 for (i=0; i<MAX_CHANNEL; i++)
00911 {
00912 if (infoHeader[i].npts>0)
00913 {
00914 order=i;
00915 break;
00916 }
00917 }
00918 if ((order>=0)||(drawing.day==1))
00919 {
00920 if (drawing.title[0]==0)
00921 {
00922 char tt[32];
00923 sprintf(tmp,"%s",infoHeader[order].station);
00924 gdImageString(im, gdFontGetMediumBold(),
00925 2,2,
00926 (unsigned char *)tmp, black);
00927 strcpy(tt,time2str(Tmin));
00928 tt[19]=0;
00929 sprintf(tmp,"%s - ",tt);
00930 strcpy(tt,time2str(Tmax));
00931 tt[19]=0;
00932 strcat(tmp,tt);
00933 gdImageString(im, gdFontGetMediumBold(),
00934 70,2,
00935 (unsigned char *)tmp, black);
00936 }
00937 else
00938 {
00939 gdImageString(im, gdFontGetMediumBold(),
00940 2,2,
00941 (unsigned char *)drawing.title, black);
00942 }
00943 }
00944 sprintf(tmp,"rtitan%d.%d.%d",VERSION,MAJOR,MINOR);
00945 gdImageString(im, gdFontGetTiny(),
00946 1,YMAX-10,
00947 (unsigned char *)tmp, grey);
00948 sprintf(tmp,"%s.gif",gdBinFileName);
00949 fout=fopen(tmp,"wb");
00950 if (fout)
00951 {
00952 gdImageGif(im, fout);
00953 fclose(fout);
00954 }
00955 else
00956 {
00957 PrintError("error writing %s\n",outFileName);
00958 }
00959 if (im)
00960 {
00961 gdImageDestroy(im);
00962 }
00963 unlink(outFileName);
00964 Rename(tmp,outFileName);
00965 }
00966
00970 void CloseGifFile(void)
00971 {
00972 char line[128];
00973 int i;
00974 int ok;
00975 memset(line,0,128);
00976 if (gdBinFile==NULL)
00977 {
00978 return;
00979 }
00980 ok=-1;
00981 for (i=0; i<MAX_CHANNEL; i++)
00982 {
00983 if (infoHeader[i].npts<=0)
00984 {
00985 continue;
00986 }
00987 Vavg[i]/=infoHeader[i].npts;
00988 Eavg[i]=sqrt(Eavg[i]/(double)infoHeader[i].npts);
00989 Vmin[i]-=Vavg[i];
00990 Vmax[i]-=Vavg[i];
00991 ok=i;
00992 UpdateInfoHeader(i);
00993 }
00994 fclose(gdBinFile);
00995 gdBinFile=fopen(gdBinFileName,"rb");
00996 if (ok>=0)
00997 {
00998 if ((drawing.outfile[0])!=0)
00999 {
01000 strcpy(line,drawing.outfile);
01001 }
01002 else
01003 {
01004 strcpy(line,FileName("", ".gif", ok, fileNameOptions&(~ADD_CHANNEL_CODE)));
01005 }
01006 PlotImage(line);
01007 PrintLog("OUTPUT: %s\n",line);
01008 }
01009 fclose(gdBinFile);
01010 gdBinFile=NULL;
01011 unlink(gdBinFileName);
01012 for (i=0; i<MAX_CHANNEL; i++)
01013 {
01014 infoHeader[i].npts=0;
01015 }
01016 if (skipTime>-1)
01017 {
01018 FILE *f;
01019 f=fopen("skip","wt");
01020 if (f!=NULL)
01021 {
01022 fprintf(f,"%d",(int)(correctedTime.usecond>>32)-60);
01023 fclose(f);
01024 }
01025 }
01026 }
01027
01028 #else
01029 void CloseGifFile(void)
01030 {
01031 }
01032 void AddGifData(int channel)
01033 {
01034 PrintError("GIF format not supported\n");
01035 }
01036 int ParseImageOptions(char *cmd)
01037 {
01038 return(0);
01039 }
01040 #endif