enum FitsFile::ImageType FitsFile::GetCurrentImageType() { CheckOpen(); int bitPixInt = 0, status = 0; fits_get_img_type(_fptr, &bitPixInt, &status); CheckStatus(status); enum ImageType imageType; switch(bitPixInt) { case BYTE_IMG: imageType = Int8ImageType; break; case SHORT_IMG: imageType = Int16ImageType; break; case LONG_IMG: imageType = Int32ImageType; break; case FLOAT_IMG: imageType = Float32ImageType; break; case DOUBLE_IMG: imageType = Double64ImageType; break; default: throw FitsIOException("Unknown image type returned"); } return imageType; }
void *readFits(const Config *para, int *bitpix, int *status, long naxes[2], double (**convert)(void *,long )){ /* Reads fits file and return info. "convert" is a pointer to a pointer of a function. */ if(para->coordType != CART){ fprintf(stderr,"%s: fits file detected. coord should be set to cart for image coordinates. Exiting...\n",MYNAME); exit(EXIT_FAILURE); } fitsfile *fptr; fits_open_file(&fptr, para->fileRegInName, READONLY, status); if(*status == FILE_NOT_OPENED){ fprintf(stderr,"%s: %s not found. Exiting...\n",MYNAME,para->fileRegInName); exit(EXIT_FAILURE); } fits_get_img_type(fptr, bitpix, status); fits_get_img_size(fptr, 2, naxes, status); long fpixel[2]; fpixel[0] = fpixel[1] = 1; void *result; char *table_CHAR; short *table_SHORT; long *table_LONG; float *table_FLOAT; double *table_DOUBLE; fprintf(stderr,"Reading fits file (format detected: "); switch (*bitpix){ case BYTE_IMG: fprintf(stderr,"BYTE)...\n"); table_CHAR = (char *)malloc(naxes[0]*naxes[1]*sizeof(char)); fits_read_pix(fptr,TBYTE,fpixel,naxes[0]*naxes[1],NULL,table_CHAR,NULL,status); result = (void *)table_CHAR; *convert = convertCHAR; break; case SHORT_IMG: fprintf(stderr,"SHORT)...\n"); table_SHORT = (short *)malloc(naxes[0]*naxes[1]*sizeof(short)); fits_read_pix(fptr,TSHORT,fpixel,naxes[0]*naxes[1],NULL,table_SHORT,NULL,status); result = (void *)table_SHORT; *convert = convertSHORT; break; case LONG_IMG: fprintf(stderr,"LONG)...\n"); table_LONG = (long *)malloc(naxes[0]*naxes[1]*sizeof(long)); fits_read_pix(fptr,TLONG,fpixel,naxes[0]*naxes[1],NULL,table_LONG,NULL,status); result = (void *)table_LONG; *convert = convertLONG; break; case FLOAT_IMG: fprintf(stderr,"FLOAT)...\n"); table_FLOAT = (float *)malloc(naxes[0]*naxes[1]*sizeof(float)); fits_read_pix(fptr,TFLOAT,fpixel,naxes[0]*naxes[1],NULL,table_FLOAT,NULL,status); result = (void *)table_FLOAT; *convert = convertFLOAT; break; case DOUBLE_IMG: fprintf(stderr,"DOUBLE)...\n"); table_DOUBLE = (double *)malloc(naxes[0]*naxes[1]*sizeof(double)); fits_read_pix(fptr,TDOUBLE,fpixel,naxes[0]*naxes[1],NULL,table_DOUBLE,NULL,status); result = (void *)table_DOUBLE; *convert = convertDOUBLE; break; default: fprintf(stderr,"NULL) \n%s: fits format not recognized. Exiting...\n",MYNAME); exit(EXIT_FAILURE); } fits_close_file(fptr, status); if (*status) fits_report_error(stderr, *status); return result; }
image_str *image_create_from_fits(char *filename) { fitsfile *fits; char buf[FLEN_CARD]; image_str *image = NULL; int status = 0; /* Error code for CFITSIO library */ int Ndims = 0; int bitpix = 0; long Npixels = 0; long firstpix[2] = {1, 1}; long fits_dims[2] = {1, 1}; if(!filename || !file_exists_and_normal(filename)) return NULL; fits_open_file(&fits, filename, READONLY, &status); do { /* read dimensions */ fits_get_img_dim(fits, &Ndims, &status); fits_get_img_size(fits, 2, fits_dims, &status); fits_get_img_type(fits, &bitpix, &status); if(Ndims < 2){ int Nhdus = 0; int hdu = 0; int type = 0; fits_get_num_hdus(fits, &Nhdus, &status); fits_get_hdu_num(fits, &hdu); if(hdu < Nhdus){ /* dprintf("Moving to HDU %d of %d\n", hdu + 1, Nhdus); */ fits_movabs_hdu(fits, hdu + 1, &type, &status); } else { /* dprintf("Error: FITS images with less than 2 dimensions are not supported\n"); */ /* fits_close_file(fits, &status); */ /* return NULL; */ break; } } } while(Ndims < 2); if(status || Ndims > 2){ if(Ndims > 2) dprintf("Error: FITS images with more than 2 dimensions are not supported\n"); fits_close_file(fits, &status); return image; } Npixels = fits_dims[0]*fits_dims[1]; if(bitpix == DOUBLE_IMG || bitpix == FLOAT_IMG){ double *data = (double *) malloc(Npixels * sizeof(double)); fits_read_pix(fits, TDOUBLE, firstpix, Npixels, NULL, data, NULL, &status); image = image_create_with_data(fits_dims[0], fits_dims[1], (u_int16_t *)data); image->type = IMAGE_DOUBLE; } else { u_int16_t *data = (u_int16_t *) malloc(Npixels * sizeof(u_int16_t)); fits_read_pix(fits, TUSHORT, firstpix, Npixels, NULL, data, NULL, &status); image = image_create_with_data(fits_dims[0], fits_dims[1], data); } /* Read all keywords we may need */ image_keywords_from_fits(image, fits); /* Rewind the header */ fits_read_record(fits, 0, buf, &status); image->coords = image_keyword_get_coords(image); if(image->coords.ra0 == 0 && image->coords.dec0 == 0){ image->coords.ra0 = 15.0*image_keyword_get_sexagesimal(image, "RA"); image->coords.dec0 = image_keyword_get_sexagesimal(image, "DEC"); } image->time = time_str_from_date_time(image_keyword_get_string(image, "TIME")); fits_close_file(fits, &status); return image; }
// getImageToArray: extract a sub-section from an image HDU, return array void *getImageToArray(fitsfile *fptr, int *dims, double *cens, int *odim1, int *odim2, int *bitpix, int *status){ int naxis=IDIM; int xcen, ycen, dim1, dim2, type; void *obuf; long totpix, totbytes; long naxes[IDIM], fpixel[IDIM], lpixel[IDIM], inc[IDIM]={1,1}; // get image dimensions and type fits_get_img_dim(fptr, &naxis, status); fits_get_img_size(fptr, IDIM, naxes, status); fits_get_img_type(fptr, bitpix, status); // get limits of extracted section if( dims && dims[0] && dims[1] ){ dim1 = min(dims[0], naxes[0]); dim2 = min(dims[1], naxes[1]); // read image section if( cens ){ xcen = cens[0]; ycen = cens[1]; } else { xcen = dim1/2; ycen = dim2/2; } fpixel[0] = (int)(xcen - ((dim1+1)/2) + 1); fpixel[1] = (int)(ycen - ((dim2+1)/2) + 1); lpixel[0] = (int)(xcen + (dim1/2)); lpixel[1] = (int)(ycen + (dim2/2)); } else { // read entire image fpixel[0] = 1; fpixel[1] = 1; lpixel[0] = naxes[0]; lpixel[1] = naxes[1]; } if( fpixel[0] < 1 ){ fpixel[0] = 1; } if( fpixel[0] > naxes[0] ){ fpixel[0] = naxes[0]; } if( fpixel[1] < 1 ){ fpixel[1] = 1; } if( fpixel[1] > naxes[1] ){ fpixel[1] = naxes[1]; } // section dimensions *odim1 = lpixel[0] - fpixel[0] + 1; *odim2 = lpixel[1] - fpixel[1] + 1; totpix = *odim1 * *odim2; // allocate space for the pixel array switch(*bitpix){ case 8: type = TBYTE; totbytes = totpix * sizeof(char); break; case 16: type = TSHORT; totbytes = totpix * sizeof(short); break; case -16: type = TUSHORT; totbytes = totpix * sizeof(unsigned short); break; case 32: type = TINT; totbytes = totpix * sizeof(int); break; case 64: type = TLONGLONG; totbytes = totpix * sizeof(long long); break; case -32: type = TFLOAT; totbytes = totpix * sizeof(float); break; case -64: type = TDOUBLE; totbytes = totpix * sizeof(double); break; default: return NULL; } // sanity check on memory limits if( totbytes > max_memory ){ return NULL; } // try to allocate that much memory if(!(obuf = (void *)malloc(totbytes))){ return NULL; } /* read the image section */ fits_read_subset(fptr, type, fpixel, lpixel, inc, 0, obuf, 0, status); // return pixel buffer (and section dimensions) return obuf; }
bool FITSImage::loadFITS ( const QString &inFilename, QProgressDialog *progress ) { int status=0, nulval=0, anynull=0; long fpixel[2], nelements, naxes[2]; char error_status[512]; qDeleteAll(starCenters); starCenters.clear(); if (mode == FITS_NORMAL && progress) { progress->setLabelText(i18n("Please hold while loading FITS file...")); progress->setWindowTitle(i18n("Loading FITS")); } if (mode == FITS_NORMAL && progress) progress->setValue(30); if (fptr) { fits_close_file(fptr, &status); if (tempFile) QFile::remove(filename); } filename = inFilename; if (filename.contains("/tmp/")) tempFile = true; else tempFile = false; filename.remove("file://"); if (fits_open_image(&fptr, filename.toAscii(), READONLY, &status)) { fits_report_error(stderr, status); fits_get_errstatus(status, error_status); if (progress) KMessageBox::error(0, i18n("Could not open file %1 (fits_get_img_param). Error %2", filename, QString::fromUtf8(error_status)), i18n("FITS Open")); return false; } if (mode == FITS_NORMAL && progress) if (progress->wasCanceled()) return false; if (mode == FITS_NORMAL && progress) progress->setValue(40); if (fits_get_img_param(fptr, 2, &(stats.bitpix), &(stats.ndim), naxes, &status)) { fits_report_error(stderr, status); fits_get_errstatus(status, error_status); if (progress) KMessageBox::error(0, i18n("FITS file open error (fits_get_img_param): %1", QString::fromUtf8(error_status)), i18n("FITS Open")); return false; } if (stats.ndim < 2) { if (progress) KMessageBox::error(0, i18n("1D FITS images are not supported in KStars."), i18n("FITS Open")); return false; } if (fits_get_img_type(fptr, &data_type, &status)) { fits_report_error(stderr, status); fits_get_errstatus(status, error_status); if (progress) KMessageBox::error(0, i18n("FITS file open error (fits_get_img_type): %1", QString::fromUtf8(error_status)), i18n("FITS Open")); return false; } if (mode == FITS_NORMAL && progress) if (progress->wasCanceled()) return false; if (mode == FITS_NORMAL && progress) progress->setValue(60); stats.dim[0] = naxes[0]; stats.dim[1] = naxes[1]; delete (image_buffer); image_buffer = NULL; image_buffer = new float[stats.dim[0] * stats.dim[1]]; if (image_buffer == NULL) { qDebug() << "Not enough memory for image_buffer"; return false; } if (mode == FITS_NORMAL && progress) { if (progress->wasCanceled()) { delete (image_buffer); return false; } } if (mode == FITS_NORMAL && progress) progress->setValue(70); nelements = stats.dim[0] * stats.dim[1]; fpixel[0] = 1; fpixel[1] = 1; qApp->processEvents(); if (fits_read_2d_flt(fptr, 0, nulval, naxes[0], naxes[0], naxes[1], image_buffer, &anynull, &status)) { fprintf(stderr, "fits_read_pix error\n"); fits_report_error(stderr, status); return false; } if (mode == FITS_NORMAL && progress) { if (progress->wasCanceled()) { delete (image_buffer); return false; } } calculateStats(); if (mode == FITS_NORMAL && progress) progress->setValue(80); //currentWidth = stats.dim[0]; // currentHeight = stats.dim[1]; qApp->processEvents(); if (mode == FITS_NORMAL) { checkWCS(); if (progress) progress->setValue(90); } if (mode == FITS_NORMAL && progress) { if (progress->wasCanceled()) { delete (image_buffer); return false; } } if (mode == FITS_NORMAL && progress) progress->setValue(100); starsSearched = false; return true; }
void newfits_(int nx, int ny, int** pic, char* w_file, int get_head, char* r_file){ int lverb = tune14_.lverb; int fio_err = 0; // for reporting file opening and writing errors char* force_file = malloc((strlen(w_file)+2)*sizeof(char)); force_file[0] = '!'; strncpy(force_file+1, w_file, strlen(w_file)); force_file[strlen(w_file)+1] = '\0'; //opening a old file if requested fitsfile* old_fptr; int old_img_type = 0; if(get_head == 1){ if (lverb > 10){ fprintf(logfile, "newfits: copying header from %s to %s \n", w_file, r_file); } fits_open_file(&(old_fptr), r_file, 0, &fio_err); if (fio_err != 0){ printf("newfits_ fitsio error in open_file: %d\n", fio_err); printf(" proceeding with minimal fits header in output\n"); fits_close_file(old_fptr, &fio_err); fio_err = 0; get_head = 0; } fits_get_img_type(old_fptr, &old_img_type, &fio_err); if( (old_img_type != (-32)) && (old_img_type != (32)) ){ printf("newfits_ old img is different size than new img"); printf(" bitpix old = %d\n", old_img_type); printf(" proceeding with minimal fits header in output\n"); fits_close_file(old_fptr, &fio_err); fio_err = 0; get_head = 0; } } else{ if (lverb > 10){ fprintf(logfile, "newfits: creating minimal header for %s \n", w_file); } get_head = 0; } //opening a new file fitsfile* fptr; fits_create_file(&(fptr), force_file, &fio_err); if (fio_err != 0){ printf("newfits_ fitsio error in create_file: %d\n", fio_err); fits_close_file(fptr, &fio_err); if(get_head == 1) fits_close_file(old_fptr, &fio_err); return; } free(force_file); //copy image or create image //copy image if (get_head == 1){ fits_copy_file(old_fptr, fptr, 1, 1, 1, &fio_err); if (fio_err != 0){ printf("newfits_ fitsio error in copy_image: %d\n", fio_err); printf(" proceeding with minimal fits header in output\n"); if (lverb > 10){ fprintf(logfile, "newfits: creating minimal header for %s \n", w_file); } fits_close_file(old_fptr, &fio_err); fio_err = 0; get_head = 0; } fits_close_file(old_fptr, &fio_err); if (fio_err != 0){ printf("newfits_ fitsio error in close_file (old): %d\n", fio_err); return; } } //create image short int fpixel = 1; short int naxis = 2; //number of axes long int nelements = (long int)(nx*ny); long int naxes[2] = {nx, ny}; if(get_head == 0){ fits_create_img(fptr, LONG_IMG, naxis, naxes, &fio_err); if (fio_err != 0){ printf("newfits_ fitsio error in create_image: %d\n", fio_err); fits_close_file(fptr, &fio_err); if(get_head == 1) fits_close_file(old_fptr, &fio_err); return; } } //recast 2d to 1d array so it is done properly int* pic_ptr = malloc_int_1darr(nx*ny); recast_int_2dto1darr(ny, nx, pic_ptr, pic); //write the array fits_write_img(fptr, TINT, fpixel, nelements, pic_ptr, &fio_err); if (fio_err != 0){ printf("newfits_ fitsio error in write_image: %d\n", fio_err); fits_close_file(fptr, &fio_err); if(get_head == 1) fits_close_file(old_fptr, &fio_err); return; } free(pic_ptr); fits_close_file(fptr, &fio_err); if (fio_err != 0){ printf("newfits_ fitsio error in close_file (new): %d\n", fio_err); return; } return; }
std::string read_image_3D(std::string pathname_3D, float *&array_2D_real, float *&array_2D_imag, int &naxis_2D, long *&naxes_2D) { TRACE_ENTER(); // open FITS image file in READONLY mode fitsfile *fptr; int status = 0; fits_open_image(&fptr, pathname_3D.c_str(), READONLY, &status); if (status != 0) { return FORMAT_STATUS(status); } // read number of HDUs in the file int nhdus = 0; fits_get_num_hdus(fptr, &nhdus, &status); if (status != 0) { return FORMAT_STATUS(status); } // we expect only one HDU in the file if (nhdus != 1) { std::ostringstream exit_oss; exit_oss << "nhdus is " << nhdus << ", not 1"; TRACE_ERROR(exit_oss.str()); return exit_oss.str(); } // read the type of the HDU int hdutype = 0; fits_movabs_hdu(fptr, nhdus, &hdutype, &status); if (status != 0) { return FORMAT_STATUS(status); } // we expect the HDU to be an image if (hdutype != IMAGE_HDU) { std::ostringstream exit_oss; exit_oss << "hdutype is " << hdutype << ", not IMAGE_HDU"; TRACE_ERROR(exit_oss.str()); return exit_oss.str(); } // read the type of data in the HDU int bitpix = 0; fits_get_img_type (fptr, &bitpix, &status); if (status != 0) { return FORMAT_STATUS(status); } // we expect the data to be floats if (bitpix != FLOAT_IMG) { std::ostringstream exit_oss; exit_oss << "bitpix is " << bitpix << ", not FLOAT_IMG"; TRACE_ERROR(exit_oss.str()); return exit_oss.str(); } // get the number of dimensions in the image int naxis_3D = 0; fits_get_img_dim (fptr, &naxis_3D, &status); if (status != 0) { return FORMAT_STATUS(status); } naxis_2D = naxis_3D-1; // we expect 3 dimensions in the image if (naxis_3D != 3) { std::ostringstream exit_oss; exit_oss << "naxis_3D is " << naxis_3D << ", not 3"; TRACE_ERROR(exit_oss.str()); return exit_oss.str(); } // get the size of each dimension in the image long *naxes_3D = new long[naxis_3D]; int maxdim = naxis_3D; fits_get_img_size(fptr, maxdim, naxes_3D, &status); if (status != 0) { return FORMAT_STATUS(status); } naxes_2D = new long[naxis_2D]; for (int i = 0; i < naxis_2D; i++) { naxes_2D[i] = naxes_3D[i]; } // we expect two sub-images in the third dimension if (naxes_3D[2] != 2) { std::ostringstream exit_oss; exit_oss << "naxes_2D[2] is " << naxes_2D[2] << ", not 2"; TRACE_ERROR (exit_oss.str()); return exit_oss.str(); } // fits_read_subset long *fpixel = new long[naxis_3D]; for (int i = 0; i < naxis_3D; i++) { fpixel[i] = 1; } long *lpixel = new long[naxis_3D]; for (int i = 0; i < naxis_3D; i++) { lpixel[i] = naxes_3D[i]; } long *inc = new long[naxis_3D]; for (int i = 0; i < naxis_3D; i++) { inc[i] = 1; } float nulval = 0; long nelements_2D = 1; for (int i = 0; i < naxis_2D; i++) { nelements_2D = nelements_2D*naxes_2D[i]; } int anynul = 0; // read array_2D_real array_2D_real = new float[nelements_2D]; fpixel[2] = 1; lpixel[2] = 1; fits_read_subset(fptr, TFLOAT, fpixel, lpixel, inc, &nulval, array_2D_real, &anynul, &status); // read array_2D_imag array_2D_imag = new float[nelements_2D]; fpixel[2] = 2; lpixel[2] = 2; fits_read_subset(fptr, TFLOAT, fpixel, lpixel, inc, &nulval, array_2D_imag, &anynul, &status); // free arrays delete [] inc; delete [] lpixel; delete [] fpixel; // test read result if (status != 0) { return FORMAT_STATUS(status); } // close the FITS image file fits_close_file(fptr, &status); if (status != 0) { return FORMAT_STATUS(status); } return "READ_OK"; }
std::string read_image(std::string pathname, float *&array, int &naxis, long *&naxes) { TRACE_ENTER(); // open FITS image file in READONLY mode fitsfile *fptr; int status = 0; fits_open_image(&fptr, pathname.c_str(), READONLY, &status); if (status != 0) { return FORMAT_STATUS(status); } // read number of HDUs in the file int nhdus = 0; fits_get_num_hdus(fptr, &nhdus, &status); if (status != 0) { return FORMAT_STATUS(status); } // we expect only one HDU in the file if (nhdus != 1) { std::ostringstream exit_oss; exit_oss << "nhdus is " << nhdus << ", not 1"; TRACE_ERROR(exit_oss.str()); return exit_oss.str(); } // read the type of the HDU int hdutype = 0; fits_movabs_hdu(fptr, nhdus, &hdutype, &status); if (status != 0) { return FORMAT_STATUS(status); } // we expect the HDU to be an image if (hdutype != IMAGE_HDU) { std::ostringstream exit_oss; exit_oss << "hdutype is " << hdutype << ", not IMAGE_HDU"; TRACE_ERROR(exit_oss.str()); return exit_oss.str(); } // read the type of data in the HDU int bitpix = 0; fits_get_img_type (fptr, &bitpix, &status); if (status != 0) { return FORMAT_STATUS(status); } // we expect the data to be floats if (bitpix != FLOAT_IMG) { std::ostringstream exit_oss; exit_oss << "bitpix is " << bitpix << ", not FLOAT_IMG"; TRACE_ERROR(exit_oss.str()); return exit_oss.str(); } // get the number of dimensions in the image naxis = 0; fits_get_img_dim (fptr, &naxis, &status); if (status != 0) { return FORMAT_STATUS(status); } // we expect 2 or 3 dimensions in the image if ((naxis < 2) || (naxis > 3)) { std::ostringstream exit_oss; exit_oss << "naxis is " << naxis << ", neither 2 nor 3"; TRACE_ERROR(exit_oss.str()); return exit_oss.str(); } // get the size of each dimension in the image naxes = new long[naxis]; int maxdim = naxis; fits_get_img_size(fptr, maxdim, naxes, &status); if (status != 0) { return FORMAT_STATUS(status); } // fits_read_subset long *fpixel = new long[naxis]; for (int i = 0; i < naxis; i++) { fpixel[i] = 1; } long *lpixel = new long[naxis]; for (int i = 0; i < naxis; i++) { lpixel[i] = naxes[i]; } long *inc = new long[naxis]; for (int i = 0; i < naxis; i++) { inc[i] = 1; } float nulval = 0; long nelements = 1; for (int i = 0; i < naxis; i++) { nelements = nelements * naxes[i]; } array = new float[nelements]; int anynul = 0; fits_read_subset(fptr, TFLOAT, fpixel, lpixel, inc, &nulval, array, &anynul, &status); delete [] inc; delete [] lpixel; delete [] fpixel; if (status != 0) { return FORMAT_STATUS(status); } // close the FITS image file fits_close_file(fptr, &status); if (status != 0) { return FORMAT_STATUS(status); } return "READ_OK"; }
// getImageToArray: extract a sub-section from an image HDU, return array void *getImageToArray(fitsfile *fptr, int *dims, double *cens, char *slice, int *odim1, int *odim2, int *bitpix, int *status){ int i, naxis; int xcen, ycen, dim1, dim2, type; int tstatus = 0; int doscale = 0; void *obuf; long totpix, totbytes; long naxes[IDIM], fpixel[IDIM], lpixel[IDIM], inc[IDIM]; double bscale = 1.0; double bzero = 0.0; char comment[81]; char *s, *tslice; int nslice, idx, iaxis0, iaxis1; int iaxes[2] = {0, 1}; int saxes[IDIM] = {0, 0, 0, 0}; // seed buffers for(i=0; i<IDIM; i++){ naxes[i] = 0; fpixel[i] = 1; lpixel[i] = 1; inc[i] = 1; } // get image dimensions and type fits_get_img_dim(fptr, &naxis, status); fits_get_img_size(fptr, min(IDIM,naxis), naxes, status); fits_get_img_type(fptr, bitpix, status); if( naxis < 2 ){ *status = BAD_DIMEN; return NULL; } // parse slice string into primary axes and slice axes if( slice && *slice ){ tslice = (char *)strdup(slice); for(s=(char *)strtok(tslice, " :,"), nslice=0, idx=0; (s != NULL) && (nslice < IDIM); s=(char *)strtok(NULL," :,"), nslice++){ if( !strcmp(s, "*") ){ if( idx < 2 ){ iaxes[idx++] = nslice; } } else { saxes[nslice] = atoi(s); if( (saxes[nslice] < 1) || (saxes[nslice] > naxes[nslice]) ){ *status = SEEK_ERROR; return NULL; } } } free(tslice); } // convenience variables for the primary axis indexes iaxis0 = iaxes[0]; iaxis1 = iaxes[1]; // get limits of extracted section if( dims && dims[0] && dims[1] ){ dim1 = min(dims[0], naxes[iaxis0]); dim2 = min(dims[1], naxes[iaxis1]); // read image section if( cens ){ xcen = cens[0]; ycen = cens[1]; } else { xcen = dim1/2; ycen = dim2/2; } fpixel[iaxis0] = (int)(xcen - (dim1+1)/2); fpixel[iaxis1] = (int)(ycen - (dim2+1)/2); lpixel[iaxis0] = (int)(xcen + (dim1/2)); lpixel[iaxis1] = (int)(ycen + (dim2/2)); } else { // read entire image fpixel[iaxis0] = 1; fpixel[iaxis1] = 1; lpixel[iaxis0] = naxes[iaxis0]; lpixel[iaxis1] = naxes[iaxis1]; } // stay within image limits fpixel[iaxis0] = max(fpixel[iaxis0], 1); fpixel[iaxis0] = min(fpixel[iaxis0], naxes[iaxis0]); lpixel[iaxis0] = max(lpixel[iaxis0], 1); lpixel[iaxis0] = min(lpixel[iaxis0], naxes[iaxis0]); fpixel[iaxis1] = max(fpixel[iaxis1], 1); fpixel[iaxis1] = min(fpixel[iaxis1], naxes[iaxis0]); lpixel[iaxis1] = max(lpixel[iaxis1], 1); lpixel[iaxis1] = min(lpixel[iaxis1], naxes[iaxis0]); // for sliced dimensions, set first and last pixel to the specified slice for(i=0; i<min(IDIM,naxis); i++){ if( saxes[i] ){ // 1 pixel slice in this dimension fpixel[i] = saxes[i]; lpixel[i] = saxes[i]; // stay within image limits fpixel[i] = max(fpixel[i], 1); fpixel[i] = min(fpixel[i], naxes[i]); lpixel[i] = max(lpixel[i], 1); lpixel[i] = min(lpixel[i], naxes[i]); } } // section dimensions *odim1 = lpixel[iaxis0] - fpixel[iaxis0] + 1; *odim2 = lpixel[iaxis1] - fpixel[iaxis1] + 1; totpix = *odim1 * *odim2; // make sure we have an image with valid dimensions size if( totpix <= 1 ){ *status = NEG_AXIS; return NULL; } // are we scaling? fits_read_key(fptr, TDOUBLE, "BSCALE", &bscale, comment, &tstatus); if( tstatus != VALUE_UNDEFINED ){ fits_read_key(fptr, TDOUBLE, "BZERO", &bzero, comment, &tstatus); } if( (bscale != 1.0) || (bzero != 0.0) ){ doscale = 1; } // allocate space for the pixel array switch(*bitpix){ case 8: if( doscale ){ // scaled data has to be float *bitpix = -32; type = TFLOAT; totbytes = totpix * sizeof(float); } else { type = TBYTE; totbytes = totpix * sizeof(char); } break; case 16: if( doscale ){ // scaled data has to be float *bitpix = -32; type = TFLOAT; totbytes = totpix * sizeof(float); } else { type = TSHORT; totbytes = totpix * sizeof(short); } break; case -16: if( doscale ){ // scaled data has to be float *bitpix = -32; type = TFLOAT; totbytes = totpix * sizeof(float); } else { type = TUSHORT; totbytes = totpix * sizeof(unsigned short); } break; case 32: if( doscale ){ // scaled data has to be float *bitpix = -32; type = TFLOAT; totbytes = totpix * sizeof(float); } else { type = TINT; totbytes = totpix * sizeof(int); } break; case 64: if( doscale ){ // scaled data has to be float *bitpix = -32; type = TFLOAT; totbytes = totpix * sizeof(float); } else { type = TLONGLONG; totbytes = totpix * sizeof(long long); } break; case -32: type = TFLOAT; totbytes = totpix * sizeof(float); break; case -64: type = TDOUBLE; totbytes = totpix * sizeof(double); break; default: return NULL; } #if EM // sanity check on memory limits if( totbytes > max_memory ){ *status = MEMORY_ALLOCATION; return NULL; } #endif // try to allocate that much memory if(!(obuf = (void *)malloc(totbytes))){ *status = MEMORY_ALLOCATION; return NULL; } /* read the image section */ fits_read_subset(fptr, type, fpixel, lpixel, inc, 0, obuf, 0, status); // return pixel buffer (and section dimensions) return obuf; }