//--------------------------------------------------------------------------- /* ************************************************* * PHOTZIP * * A 16bit FITS Images Compression Utility * * Lior Shamir & Robert Nemiroff * * Michigan Technological University * * Houghton, MI 49931 * ************************************************* */ #include #include #include #include /* this should be linked to the header file of cfitsio */ #include "../fits/fitsio.h" //--------------------------------------------------------------------------- //unsigned short **data; /* "data" should store the fits image's pixels values */ long width,height; /* dimensions of the fits image */ unsigned short median=0; typedef struct DATUM { unsigned short value; unsigned short background; long order; }datum; datum **data; typedef struct PIXEL { unsigned short value; unsigned short x,y; }pixel; pixel *pixel_array=NULL; unsigned short S[4028],B[4028]; /* use global memory for avoiding using the stack */ char header[200][256]; /* use this for the header */ int image_type,anynull,simple,bitpix,extend,keysnum; long pcount,gcount; unsigned short Find_Nth_Item(unsigned short *array, unsigned short num, unsigned short item) { unsigned short pivot,index,s_index=0,b_index=0,eq=0; if (num==1) return(array[0]); pivot=(unsigned short)(random()%num); for (index=0;index=array[pivot]) B[b_index++]=array[index]; if (array[index]==array[pivot]) eq++; } if (eq==num) return(array[0]); if (s_index==item) return(array[pivot]); if (s_index<=item) { memmove(array,B,b_index*sizeof(unsigned short)); /* use global memory and not the stack */ return(Find_Nth_Item(array,b_index,item-s_index)); } else { memmove(array,S,s_index*sizeof(unsigned short)); /* use global memory and not the stack */ return(Find_Nth_Item(array,s_index,item)); } } /* sort function - a function for using quick sort C function for finding the midean value */ int sort_function(const void *a, const void *b) { return((*((unsigned short *)(a))>*((unsigned short *)(b)))*2-1); } int sort_function1(const void *a, const void *b) { return((((pixel *)a)->value>((pixel *)b)->value)*2-1); } /********************************************************************* /* ***************************** LoadFits **************************** purpose: load a FITS file. input: fits_file_path: the file name of the output file. sort: if 1 - the pixels in the frame are sorted for getting the midean value. If "t" parameter is specified, then the sorting is required, otherwise the pixel values are not sorted. returned value: 1 if succeeded. 0 if failed. */ int LoadFits(char *fits_file_path,int sort) { unsigned short val; fitsfile *fptr; /* pointer to the FITS file; defined in fitsio.h */ int status, ii, jj,x; unsigned short *short_array; long nelements, exposure; int keycount; int naxis = 2; long naxes[2]; status=0; /* very important - the status must be initialized before calling to fitsio routines */ fits_open_image(&fptr,fits_file_path,0,&status); if (status) return(0); fits_read_imghdr(fptr,MAX_COMPRESS_DIM,&simple,&bitpix, &naxis,naxes,&pcount,&gcount, &extend, &status); /* validate the attributes of the input file */ if (status) return(0); /* read the header */ fits_get_hdrspace(fptr,&keysnum,NULL,&status); if (status) return(0); for (keycount=1;keycount<=keysnum+1;keycount++) { char keyword[256]; int a; fits_read_record(fptr,keycount,keyword,&status); a=0; while (keyword[a]) { header[keycount][a]=keyword[a]; a++; } header[keycount][a]='\0'; } /* read the data */ if (naxis!=2) { printf("Input FITS doesn't have exactly two axis\n"); return(0); } if (bitpix!=16) { printf("Input FITS is not a 16 bit/pixel image\n"); return(0); } /* allocate memory for the image */ width=naxes[0]; height=naxes[1]; data=new datum *[width]; if (!data) return(0); /* memory allocation failed */ for (x=0;x=width-half_width_size) x=width-half_width_size-1; if (y<=half_width_size) y=half_width_size; if (y>=height-half_width_size) y=height-half_width_size-1; /* get the pixel counts around the star and put them in an array */ for (yc=y-half_width_size;yc<=y+half_width_size;yc++) for (xc=x-half_width_size;xc<=x+half_width_size;xc++) pixel_counts[num++]=data[xc][yc].value; /* find the midean value */ bg=Find_Nth_Item(pixel_counts,num,(long)(ceil(num/2))); return(bg); } /* ******************************************************************* /* ********************* GetPixelsBackground ************************* purpose: compute a background value void GetPixelsBackground(int half_width_size) { long x,y,xc,yc; unsigned short background; for (y=0;ypow(2,floor(log10(sigma*max_diff)/log10(2)))) quantisized_value+=(unsigned short)pow(2,ceil(log10(sigma*max_diff)/log10(2))); return(quantisized_value); } /*********************************************************************** /* ************************** CompressFits ***************************** purpose: quantisize a pixel's value according to its sigma and max_diff input: min_bright - the minimum sigmas over the backgrounf of a pixel to be quantisized (the d switch in the command line). half_width_size: the half width of the background window. (the s switch in the command line) max_diff - the maximum allowed difference between the pixel's value and the pixel's value in the compressed/decompressed frame (the b switch in the command line) threshold - a threshold for a pixel's value to be quantisized. (the t switch of the command line). returned value: 1 if succeeded, otherwise - 0. */ int CompressFits(double min_bright,double max_diff,int half_width_size,double threshold) { long x,y; // GetPixelsBackground(half_width_size); /* truncate all values which are under the midean value */ for (y=0;y2 && argv[arg_index][0]=='-' && strchr(argv[arg_index],'b')) { max_diff=atof(strchr(argv[arg_index],'b')+1); if (max_diff<0 || max_diff>20) { printf("Invalid -b value '%s'.\n",strchr(argv[arg_index],'b')+1); return(0); } last_switch=arg_index; } /* check if -d was specified */ if (strlen(argv[arg_index])>2 && argv[arg_index][0]=='-' && strchr(argv[arg_index],'d')) { min_bright=atof(strchr(argv[arg_index],'d')+1); if (min_bright<0 || min_bright>20) { printf("Invalid -d value '%s'.\n",strchr(argv[arg_index],'d')+1); return(0); } last_switch=arg_index; } /* check if -s was specified */ if (strlen(argv[arg_index])>2 && argv[arg_index][0]=='-' && strchr(argv[arg_index],'s')) { half_width_size=atoi(strchr(argv[arg_index],'s')+1); if (half_width_size<1) { printf("Invalid -s value '%s'.\n",strchr(argv[arg_index],'s')+1); return(0); } last_switch=arg_index; } /* check if -t was specified */ if (strlen(argv[arg_index])>2 && argv[arg_index][0]=='-' && strchr(argv[arg_index],'t')) { threshold=atof(strchr(argv[arg_index],'t')+1); if (threshold<0) { printf("Invalid -t value '%s'.\n",strchr(argv[arg_index],'t')+1); return(0); } last_switch=arg_index; } } if (argc<3 || last_switch