diff --git a/Makefile b/Makefile index fe426b5..f8fc1d3 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ atpdec: $(OBJS) main.o: main.c cmap.h dsp.o: dsp.c filtercoeff.h filter.h filter.o: filter.c filter.h -image.o: image.c +image.o: image.c satcal.h clean: rm -f *.o atpdec diff --git a/README b/README index c754207..dc69da7 100644 --- a/README +++ b/README @@ -14,13 +14,15 @@ into a soundfile with any soundcard. Atpdec will convert these sounfiles into .png images. -For each soundfile up to 4 images could be generated : +For each soundfile up to 6 images could be generated : 1. Raw image : contains the 2 transmitted channel images + telemetry and synchro pulses. 2. Calibrated channel A image 3. Calibrated channel B image - 4. False color image + 4. Temperature compensed I.R image + 5. False color image + 6. pixel distribution statistique (usefull for false color cmap debugging). Input soundfiles must be mono signal sampled at 11025 Hz. Atpdec use libsnd to read soundfile, so any sound file format supported by libsnd @@ -32,34 +34,10 @@ Atpdec is written in plain standart C and must be very portable. It was only tested on Linux Suse 8.2, but must work on any Unix platform. Just adapt the Makefile and type make (sorry no configure). -atpdec use libsnd, libpng and libm +atpdec use libsnd, libpng and libm. snd.h and png.h header must be present on your system. If they are not on standard path, edit the include path in the Makefile. USAGE -atpdec [options] soundfile - --c file.png -Use a given colormap for false color generation. Default : Internal colormap. --i [r|a|b|c] -Toggle raw (r) , channel A (a) , channel B (b) or false color (c) output. -Default : "abc" --d directory -Optional images destination directory. Default : sounfile directory. --s Output 8bits grayscale images for chanel A|B and raw images. Default :16bits - -Generated image are in png format, 16 or 8bits greyscale for raw and channel A|B images, -24bits RVB for false color. -Image names are soundfilename-x.png, where x is : - -r for raw images - -satellite instrument number (1,2,3A,3B,4,5) for channel A|B images - -c for false colors. - - -EXAMPLE -atpdec -d test -i ac 09121333.wav - -Will process the 09121333.wav file and generate channel A test/09121333-2.png and false color test/09121333-c.png image files. - - +see atpdec.1 man page. diff --git a/TODO b/TODO index 836a96b..6a316b9 100644 --- a/TODO +++ b/TODO @@ -3,12 +3,11 @@ ATPDEC TODO List - Could be useful to read data directly from /dev/dsp - False color generation give various results , from good to very poor. - Temperature calibration for IR channel could be helpful in this area. - GUI : I'm not a GUI man , but if someone want to do the job .... - Optimisation : Don't do anything in order to run fast. There is plenty - possibility to increase performance (but on my 1.7GHz celeron , it's + room for performance improuvement (but on my 1.7GHz celeron , it's already faster than real time...) diff --git a/atpdec.1 b/atpdec.1 index 84fd763..23b1781 100644 --- a/atpdec.1 +++ b/atpdec.1 @@ -2,8 +2,8 @@ .SH NAME atpdec .SH OVERVIEW -atpdec is a decoder for NOAA weather satellite images (ATP). -It takes soundfiles recorded from an ATP receiver and convert them into .png images. +atpdec is a decoder for NOAA POES weather satellite images. +It takes soundfiles recorded from a dedicated receiver and convert them into .png images. .SH SYNOPSIS .B atpdec .I "[options]" soundfiles ... @@ -14,17 +14,21 @@ It takes soundfiles recorded from an ATP receiver and convert them into .png ima Use a private colormap for false color generation. Default : Internal colormap. .TP .br -.B \-i [r|a|b|c] -Toggle raw (r) , channel A (a) , channel B (b) or false color (c) output. -Default : "abc" +.B \-i [r|a|b|c|t|d] +Toggle raw (r) , channel A (a) , channel B (b) , false color (c) , temperatue (t) or pixel distrubution (d) output. +Default : "ac" .TP .br .B \-d directory Optional images destination directory. Default : soundfile directory. .TP .br -.B \-s -Output 8bits grayscale image for channel A|B and raw images. Default : 16bits images. +.B \-p +Output 16bits grayscale image for channel A|B and raw images. Default : 8bits images. +.TP +.br +.B \-s n +Satellite ident : n=0 :NOOA-15 n=1 :NOAA-17 (used by Temperature compensation step).Default : NOAA17 Generated image are in png format, 16 or 8bits greyscale for raw and channel A|B images, 24bits RVB for false color. @@ -32,6 +36,7 @@ Image names are soundfilename-x.png, where x is : -r for raw images -satellite instrument number (1,2,3A,3B,4,5) for channel A|B images -c for false colors. + -d for pixel distribution stats. .SH DESCRIPTION @@ -46,7 +51,7 @@ into a soundfile with any soundcard. Atpdec will convert these sounfiles into .png images. -For each soundfile up to 4 images could be generated : +For each soundfile up to 6 images could be generated : 1) Raw image : contains the 2 transmitted channel images + telemetry and synchro pulses. Raw image is not calibrated, so it could be too dark or too light depending of the recording level. @@ -55,7 +60,11 @@ For each soundfile up to 4 images could be generated : 3) Calibrated channel B image -4) False color image +4) Temperature compensed I.R image + +5) False color image + +6) Pixel distribution statistique image (for cmap debugging only). Input soundfiles must be mono signal sampled at 11025 Hz. Atpdec use libsnd to read soundfile, so any sound file format supported by libsnd diff --git a/dsp.c b/dsp.c index 6dd5cd6..070a704 100755 --- a/dsp.c +++ b/dsp.c @@ -125,7 +125,7 @@ int n; } mult=(double)Fi/4800.0*fr*FreqLine; - pvbuff[n]=rsfir(&(ambuff[idxam]),rsfilter,RSFilterLen,offset,mult)*RSMULT/2.0; + pvbuff[n]=rsfir(&(ambuff[idxam]),rsfilter,RSFilterLen,offset,mult)*RSMULT*128.0; shift=(int)((RSMULT-offset+mult-1)/mult); offset=shift*mult+offset-RSMULT; diff --git a/main.c b/main.c index f7d57e7..e85c9c5 100644 --- a/main.c +++ b/main.c @@ -61,7 +61,7 @@ return(sf_read_float(inwav,sample,nb)); } png_text text_ptr[2]={ -{ PNG_TEXT_COMPRESSION_NONE, "Software", "atpdec (Thierry Leconte)",35 } +{ PNG_TEXT_COMPRESSION_NONE, "Software", "atpdec (c) Thierry Leconte 2003",32 } }; static int ImageOut(char *filename,float **prow,int nrow,int depth,int width,int offset) { @@ -110,10 +110,10 @@ for(n=0;n255) x=255; - if(x<0) x=0; - if(y>255) y=255; - if(y<0) y=0; + y=(int)(pixelv[i+85]); + x=(int)(pixelv[i+1125]); distrib[y][x]+=1; if(distrib[y][x]> max) max=distrib[y][x]; } } df=fopen(filename,"w"); + +printf("Writing %s\n",filename); + fprintf(df,"P2\n#max %d\n",max); fprintf(df,"256 256\n255\n"); for(y=0;y<256;y++) @@ -278,28 +275,35 @@ for(y=0;y<256;y++) fprintf(df,"%d\n",(int)((255.0*(double)(distrib[y][x]))/(double)max)); fclose(df); } -#endif extern int Calibrate(float **prow,int nrow,int offset); +extern int Temperature(float **prow,int nrow,int ch, int offset); extern int optind,opterr; extern char *optarg; +int satnum=1; + +static void usage(void) +{ + fprintf(stderr,"atpdec [options] soundfiles ...\n"); + fprintf(stderr,"options:\n-d directory\n-i [a|b|c|t|d]\n-c cmap.png\n-p\n-s satnumber\n"); +} main(int argc, char **argv) { char pngfilename[1024]; char name[1024]; char *pngdirname=NULL; -char imgopt[20]="abc"; +char imgopt[20]="ac"; float *prow[3000]; const char *chid[6]={ "1","2","3A","4","5","3B"}; -int depth=16; +int depth=8; int n,nrow; int ch; int c; opterr=0; -while ((c=getopt(argc,argv,"c:d:i:s"))!=EOF) { +while ((c=getopt(argc,argv,"c:d:i:ps:"))!=EOF) { switch(c) { case 'd': pngdirname=optarg; @@ -310,9 +314,18 @@ while ((c=getopt(argc,argv,"c:d:i:s"))!=EOF) { case 'i': strcpy(imgopt,optarg); break; + case 'p': + depth=16; + break; case 's': - depth=8; + satnum=atoi(optarg); + if(satnum<0 || satnum > 1) { + fprintf(stderr,"invalid satellite\n"); + exit(1); + } break; + default: + usage(); } } @@ -346,12 +359,12 @@ sf_close(inwav); /* raw image */ if(strchr(imgopt,(int)'r')!=NULL){ -sprintf(pngfilename,"%s/%s.png",pngdirname,name); +sprintf(pngfilename,"%s/%s-r.png",pngdirname,name); ImageOut(pngfilename,prow,nrow,depth,2080,0); } /* Channel A */ -if(((strchr(imgopt,(int)'a')!=NULL) || (strchr(imgopt,(int)'c')!=NULL))) { +if(((strchr(imgopt,(int)'a')!=NULL) || (strchr(imgopt,(int)'c')!=NULL) || (strchr(imgopt,(int)'d')!=NULL))) { ch=Calibrate(prow,nrow,85); if(ch>0) { a=1; @@ -366,18 +379,26 @@ if(((strchr(imgopt,(int)'a')!=NULL) || (strchr(imgopt,(int)'c')!=NULL))) { if(((strchr(imgopt,(int)'b')!=NULL) || (strchr(imgopt,(int)'c')!=NULL))) { ch=Calibrate(prow,nrow,1125); if(ch>0) { - b=1; if(strchr(imgopt,(int)'b')!=NULL) { - sprintf(pngfilename,"%s/%s-%s.png",pngdirname,name,chid[ch]); - ImageOut(pngfilename,prow,nrow,depth,954,1125); + sprintf(pngfilename,"%s/%s-%s.png",pngdirname,name,chid[ch]); + ImageOut(pngfilename,prow,nrow,depth,954,1125); + } + } + if(ch>2) { + b=1; + Temperature(prow,nrow,ch,1125); + if(strchr(imgopt,(int)'t')!=NULL) { + sprintf(pngfilename,"%s/%s-t.png",pngdirname,name); + ImageOut(pngfilename,prow,nrow,depth,954,1125); } } } -#ifdef DEBUG +/* distribution */ +if(a && b && strchr(imgopt,(int)'d')!=NULL){ sprintf(pngfilename,"%s/%s-d.pnm",pngdirname,name); Distrib(pngfilename,prow,nrow); -#endif +} /* color image */ if(a && b && strchr(imgopt,(int)'c')!=NULL){