@@ -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 |
@@ -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. |
@@ -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...) | |||
@@ -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 | |||
@@ -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; | |||
@@ -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;n<nrow;n++) { | |||
pv=pixelv[i+offset]; | |||
switch(depth) { | |||
case 8 : | |||
pixel[i]=(png_byte)(pv*255.0); | |||
pixel[i]=(png_byte)pv; | |||
break; | |||
case 16 : | |||
((unsigned short*)pixel)[i]=htons((unsigned short)(pv*65535.0)); | |||
((unsigned short*)pixel)[i]=htons((unsigned short)(pv*255.0)); | |||
break; | |||
} | |||
} | |||
@@ -170,8 +170,8 @@ for(n=0;n<nrow;n++) { | |||
for(i=0;i<909;i++) { | |||
int x,y; | |||
y=(int)(pixelv[i+85]*255.0); | |||
x=(int)(pixelv[i+1125]*255.0); | |||
y=(int)(pixelv[i+85]); | |||
x=(int)(pixelv[i+1125]); | |||
pixel[i]=cmap[y][x]; | |||
} | |||
png_write_row(png_ptr,(png_bytep)pixel); | |||
@@ -239,10 +239,9 @@ png_destroy_read_struct(&png_ptr,&info_ptr,NULL); | |||
return(0); | |||
} | |||
#ifdef DEBUG | |||
unsigned int distrib[256][256]; | |||
int Distrib(char *filename,float **prow,int nrow) | |||
static int Distrib(char *filename,float **prow,int nrow) | |||
{ | |||
unsigned int distrib[256][256]; | |||
int n; | |||
int x,y; | |||
int max=0; | |||
@@ -254,23 +253,21 @@ for(y=0;y<256;y++) | |||
for(n=0;n<nrow;n++) { | |||
float *pixelv; | |||
png_color pixel[909]; | |||
int i; | |||
pixelv=prow[n]; | |||
for(i=0;i<909;i++) { | |||
y=(int)(pixelv[i+85]*255.0); | |||
x=(int)(pixelv[i+1125]*255.0); | |||
if(x>255) 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){ | |||