#include #include #include #include #include #include #include #include struct image { int nx,ny,nz; float *z; double mjd; char nfd[32],observer[32]; int cospar,tracked; float exptime; }; struct image read_jpg(char *filename); void write_fits(struct image img,char *filename); double date2mjd(int year,int month,double day); double nfd2mjd(char *date); void mjd2nfd(double mjd,char *nfd); // Read fits image struct image read_fits(char *filename) { int i,j,k,l,m; qfitsloader ql; char key[FITS_LINESZ+1] ; struct image img; float s1,s2,avg,std; // Set plane ql.xtnum = 0; ql.pnum = 0; // Set loadtype ql.ptype = PTYPE_FLOAT; // Set filename ql.filename=filename; // Image size img.nx=atoi(qfits_query_hdr(filename,"NAXIS1")); img.ny=atoi(qfits_query_hdr(filename,"NAXIS2")); img.nz=1; // Initialize load if (qfitsloader_init(&ql) != 0) printf("Error initializing data loading\n"); // Test load if (qfits_loadpix(&ql) != 0) printf("Error loading actual data\n"); // Allocate image memory img.z=(float *) malloc(sizeof(float) * img.nx*img.ny*img.nz); // Fill z array for (i=0,l=0,m=0;i1) { while ((arg=getopt(argc,argv,"i:t:o:d:Z:c:T:O:b:hFs"))!=-1) { switch(arg) { case 's': tracked=1; break; case 'i': strcpy(infile,optarg); break; case 'd': delay=(double) atof(optarg); break; case 'b': nbin=atoi(optarg); break; case 'Z': tz=(double) atof(optarg); break; case 'o': strcpy(outfile,optarg); flag=1; break; case 'F': readfits=1; break; case 't': strcpy(nfd,optarg); break; case 'c': cospar=atoi(optarg); break; case 'T': exptime=atof(optarg); break; case 'O': strcpy(observer,optarg); break; case 'h': usage(); break; default: usage(); return 0; } } } else { usage(); } if (infile!=NULL) { if (nbin==1) { if (readfits==0) img=read_jpg(infile); else img=read_fits(infile); } else { if (readfits==0) raw=read_jpg(infile); else raw=read_fits(infile); img=rebin(raw,nbin); } } // Set tracked flag if (tracked==1) img.tracked=1; else img.tracked=0; if (nfd!=NULL) { // Compute time mjd=nfd2mjd(nfd); mjd+=(delay+tz)/86400.0; mjd2nfd(mjd,nfd); // Into file strcpy(img.nfd,nfd); img.mjd=mjd; } if (flag==0) sprintf(outfile,"%s.fits",img.nfd); // Set properties img.cospar=cospar; img.exptime=exptime; strcpy(img.observer,observer); if (outfile!=NULL) write_fits(img,outfile); // Free free(img.z); if (nbin!=1) free(raw.z); return 0; } struct image read_jpg(char *filename) { int i=0,j,k,l,m; unsigned long location=0; struct image img; struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPROW row_pointer[1]; unsigned char *raw_image=NULL; FILE *file; ExifData *ed; ExifEntry *entry; // Open file file=fopen(filename,"rb"); if (!file) perror("Error opening file"); // Get header info, decompress cinfo.err=jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo,file); jpeg_read_header(&cinfo,TRUE); jpeg_start_decompress(&cinfo); // Allocate memory raw_image=(unsigned char *) malloc(cinfo.output_width*cinfo.output_height*cinfo.num_components); // Read image, one scan at a time row_pointer[0]=(unsigned char *) malloc(cinfo.output_width*cinfo.num_components); while(cinfo.output_scanlineifd[0],EXIF_TAG_DATE_TIME); exif_entry_get_value(entry,img.nfd, sizeof(img.nfd)); img.nfd[4]='-'; img.nfd[7]='-'; img.nfd[10]='T'; img.nfd[20]='\0'; img.mjd=nfd2mjd(img.nfd); } */ return img; } // Write fits file void write_fits(struct image img,char *filename) { int i,j,k,l; int *ibuf; qfitsdumper qd; qfits_header *qh; char key[FITS_LINESZ+1] ; char val[FITS_LINESZ+1] ; char com[FITS_LINESZ+1] ; char lin[FITS_LINESZ+1] ; FILE *file; // Create FITS header qh=qfits_header_default(); // Add stuff qfits_header_add(qh,"BITPIX","16"," ",NULL); qfits_header_add(qh,"NAXIS","2"," ",NULL); sprintf(val,"%i",img.nx); qfits_header_add(qh,"NAXIS1",val," ",NULL); sprintf(val,"%i",img.ny); qfits_header_add(qh,"NAXIS2",val," ",NULL); qfits_header_add(qh,"BSCALE","1.0"," ",NULL); qfits_header_add(qh,"BZERO","0.0"," ",NULL); qfits_header_add(qh,"DATAMAX","255.0"," ",NULL); qfits_header_add(qh,"DATAMIN","0.0"," ",NULL); // Astrometry keywors sprintf(val,"%f",img.nx/2.0); qfits_header_add(qh,"CRPIX1",val," ",NULL); sprintf(val,"%f",img.ny/2.0); qfits_header_add(qh,"CRPIX2",val," ",NULL); qfits_header_add(qh,"CRVAL1","0.0"," ",NULL); qfits_header_add(qh,"CRVAL2","0.0"," ",NULL); qfits_header_add(qh,"CD1_1","0.0"," ",NULL); qfits_header_add(qh,"CD1_2","0.0"," ",NULL); qfits_header_add(qh,"CD2_1","0.0"," ",NULL); qfits_header_add(qh,"CD2_2","0.0"," ",NULL); qfits_header_add(qh,"CTYPE1","'RA---TAN'"," ",NULL); qfits_header_add(qh,"CTYPE2","'DEC--TAN'"," ",NULL); qfits_header_add(qh,"CUNIT1","'deg'"," ",NULL); qfits_header_add(qh,"CUNIT2","'deg'"," ",NULL); qfits_header_add(qh,"CRRES1","0.0"," ",NULL); qfits_header_add(qh,"CRRES2","0.0"," ",NULL); qfits_header_add(qh,"EQUINOX","2000.0"," ",NULL); qfits_header_add(qh,"RADECSYS","ICRS"," ",NULL); sprintf(val,"%s",img.nfd); qfits_header_add(qh,"DATE-OBS",val," ",NULL); sprintf(val,"%lf",img.mjd); qfits_header_add(qh,"MJD-OBS",val," ",NULL); sprintf(val,"%d",img.cospar); qfits_header_add(qh,"COSPAR",val," ",NULL); sprintf(val,"%f",img.exptime); qfits_header_add(qh,"EXPTIME",val," ",NULL); sprintf(val,"%s",img.observer); qfits_header_add(qh,"OBSERVER",val," ",NULL); sprintf(val,"%d",img.tracked); qfits_header_add(qh,"TRACKED",val," ",NULL); // Dump fitsheader // qfits_header_dump(qh,stdout); // Dump to file file=fopen(filename,"w"); qfits_header_dump(qh,file); fclose(file); // Fill buffer ibuf=malloc(img.nx*img.ny*sizeof(int)); for (i=0,l=0;i=0;j--) { ibuf[l]=(int) img.z[l]; l++; } } // Set parameters qd.filename=filename; qd.npix=img.nx*img.ny; qd.ptype=PTYPE_INT; qd.ibuf=ibuf; qd.out_ptype=BPP_16_SIGNED; // Dump qfits_pixdump(&qd); free(ibuf); return; } // Compute Julian Day from Date double date2mjd(int year,int month,double day) { int a,b; double jd; if (month<3) { year--; month+=12; } a=floor(year/100.); b=2.-a+floor(a/4.); if (year<1582) b=0; if (year==1582 && month<10) b=0; if (year==1582 && month==10 && day<=4) b=0; jd=floor(365.25*(year+4716))+floor(30.6001*(month+1))+day+b-1524.5; return jd-2400000.5; } // nfd2mjd double nfd2mjd(char *date) { int year,month,day,hour,min; float sec; double mjd,dday; sscanf(date,"%04d-%02d-%02dT%02d:%02d:%f",&year,&month,&day,&hour,&min,&sec); dday=day+hour/24.0+min/1440.0+sec/86400.0; mjd=date2mjd(year,month,dday); return mjd; } // Compute Date from Julian Day void mjd2nfd(double mjd,char *nfd) { double f,jd,dday; int z,alpha,a,b,c,d,e; int year,month,day,hour,min; float sec,x; jd=mjd+2400000.5; jd+=0.5; z=floor(jd); f=fmod(jd,1.); if (z<2299161) a=z; else { alpha=floor((z-1867216.25)/36524.25); a=z+1+alpha-floor(alpha/4.); } b=a+1524; c=floor((b-122.1)/365.25); d=floor(365.25*c); e=floor((b-d)/30.6001); dday=b-d-floor(30.6001*e)+f; if (e<14) month=e-1; else month=e-13; if (month>2) year=c-4716; else year=c-4715; day=(int) floor(dday); x=24.0*(dday-day); x=3600.*fabs(x); sec=fmod(x,60.); x=(x-sec)/60.; min=fmod(x,60.); x=(x-min)/60.; hour=x; sec=floor(1000.0*sec)/1000.0; sprintf(nfd,"%04d-%02d-%02dT%02d:%02d:%06.3f",year,month,day,hour,min,sec); return; }