/*--------------------------------------------------------------------------*/ int ffgsv( fitsfile *fptr, /* I - FITS file pointer */ int datatype, /* I - datatype of the value */ long *blc, /* I - 'bottom left corner' of the subsection */ long *trc , /* I - 'top right corner' of the subsection */ long *inc, /* I - increment to be applied in each dim. */ void *nulval, /* I - value for undefined pixels */ void *array, /* O - array of values that are returned */ int *anynul, /* O - set to 1 if any values are null; else 0 */ int *status) /* IO - error status */ /* Read an section of values from the primary array. The datatype of the input array is defined by the 2nd argument. Data conversion and scaling will be performed if necessary (e.g, if the datatype of the FITS array is not the same as the array being read). Undefined elements will be set equal to NULVAL, unless NULVAL=0 in which case no checking for undefined values will be performed. ANYNUL is returned with a value of .true. if any pixels are undefined. */ { int naxis, ii; long naxes[9]; LONGLONG nelem = 1; if (*status > 0) /* inherit input status value if > 0 */ return(*status); /* get the size of the image */ ffgidm(fptr, &naxis, status); ffgisz(fptr, 9, naxes, status); /* test for the important special case where we are reading the whole image */ /* this is only useful for images that are not tile-compressed */ if (!fits_is_compressed_image(fptr, status)) { for (ii = 0; ii < naxis; ii++) { if (inc[ii] != 1 || blc[ii] !=1 || trc[ii] != naxes[ii]) break; nelem = nelem * naxes[ii]; } if (ii == naxis) { /* read the whole image more efficiently */ ffgpxv(fptr, datatype, blc, nelem, nulval, array, anynul, status); return(*status); } } if (datatype == TBYTE) { if (nulval == 0) ffgsvb(fptr, 1, naxis, naxes, blc, trc, inc, 0, (unsigned char *) array, anynul, status); else ffgsvb(fptr, 1, naxis, naxes, blc, trc, inc, *(unsigned char *) nulval, (unsigned char *) array, anynul, status); } else if (datatype == TSBYTE) { if (nulval == 0) ffgsvsb(fptr, 1, naxis, naxes, blc, trc, inc, 0, (signed char *) array, anynul, status); else ffgsvsb(fptr, 1, naxis, naxes, blc, trc, inc, *(signed char *) nulval, (signed char *) array, anynul, status); } else if (datatype == TUSHORT) { if (nulval == 0) ffgsvui(fptr, 1, naxis, naxes, blc, trc, inc, 0, (unsigned short *) array, anynul, status); else ffgsvui(fptr, 1, naxis, naxes,blc, trc, inc, *(unsigned short *) nulval, (unsigned short *) array, anynul, status); } else if (datatype == TSHORT) { if (nulval == 0) ffgsvi(fptr, 1, naxis, naxes, blc, trc, inc, 0, (short *) array, anynul, status); else ffgsvi(fptr, 1, naxis, naxes, blc, trc, inc, *(short *) nulval, (short *) array, anynul, status); } else if (datatype == TUINT) { if (nulval == 0) ffgsvuk(fptr, 1, naxis, naxes, blc, trc, inc, 0, (unsigned int *) array, anynul, status); else ffgsvuk(fptr, 1, naxis, naxes, blc, trc, inc, *(unsigned int *) nulval, (unsigned int *) array, anynul, status); } else if (datatype == TINT) { if (nulval == 0) ffgsvk(fptr, 1, naxis, naxes, blc, trc, inc, 0, (int *) array, anynul, status); else ffgsvk(fptr, 1, naxis, naxes, blc, trc, inc, *(int *) nulval, (int *) array, anynul, status); } else if (datatype == TULONG) { if (nulval == 0) ffgsvuj(fptr, 1, naxis, naxes, blc, trc, inc, 0, (unsigned long *) array, anynul, status); else ffgsvuj(fptr, 1, naxis, naxes, blc, trc, inc, *(unsigned long *) nulval, (unsigned long *) array, anynul, status); } else if (datatype == TLONG) { if (nulval == 0) ffgsvj(fptr, 1, naxis, naxes, blc, trc, inc, 0, (long *) array, anynul, status); else ffgsvj(fptr, 1, naxis, naxes, blc, trc, inc, *(long *) nulval, (long *) array, anynul, status); } else if (datatype == TLONGLONG) { if (nulval == 0) ffgsvjj(fptr, 1, naxis, naxes, blc, trc, inc, 0, (LONGLONG *) array, anynul, status); else ffgsvjj(fptr, 1, naxis, naxes, blc, trc, inc, *(LONGLONG *) nulval, (LONGLONG *) array, anynul, status); } else if (datatype == TFLOAT) { if (nulval == 0) ffgsve(fptr, 1, naxis, naxes, blc, trc, inc, 0, (float *) array, anynul, status); else ffgsve(fptr, 1, naxis, naxes, blc, trc, inc, *(float *) nulval, (float *) array, anynul, status); } else if (datatype == TDOUBLE) { if (nulval == 0) ffgsvd(fptr, 1, naxis, naxes, blc, trc, inc, 0, (double *) array, anynul, status); else ffgsvd(fptr, 1, naxis, naxes, blc, trc, inc, *(double *) nulval, (double *) array, anynul, status); } else *status = BAD_DATATYPE; return(*status); }
std::shared_ptr<IImage> FITS_IO::read(const std::string& filename) { fitsfile *fitsFilePtr; int status = 0; ffopen(&fitsFilePtr, filename.c_str(), READONLY, &status); if (status) throw Common::Exception() << "ffopen failed with " << status; int bytesPerPixel = 0; int bitPixType; ffgidt(fitsFilePtr, &bitPixType, &status); if (status) throw Common::Exception() << "ffgidt failed with " << status; int imgType = 0; switch (bitPixType) { case BYTE_IMG: bytesPerPixel = 1; imgType = TBYTE; break; case SHORT_IMG: bytesPerPixel = 2; imgType = TSHORT; break; case LONG_IMG: bytesPerPixel = 4; imgType = TLONG; break; case FLOAT_IMG: bytesPerPixel = 4; imgType = TFLOAT; break; case DOUBLE_IMG: bytesPerPixel = 8; imgType = TDOUBLE; break; default: throw Common::Exception() << "image is an unsupported FITS type " << bitPixType; } int dim; ffgidm(fitsFilePtr, &dim, &status); if (status) throw Common::Exception() << "ffgidm failed with " << status; if (dim != 3) throw Common::Exception() << "image is an unsupported dimension " << dim; long int fpixel[3]; for (int i = 0; i < dim; i++) { fpixel[i] = 1; } long int sizes[3]; ffgisz(fitsFilePtr, 3, sizes, &status); if (status) throw Common::Exception() << "ffgisz failed with " << status; int width = sizes[0]; int height = sizes[1]; Tensor::Vector<int,2> size(width,height); int channels = sizes[2]; int numPixels = width * height * channels; std::vector<unsigned char> data(numPixels * bytesPerPixel); ffgpxv(fitsFilePtr, imgType, fpixel, numPixels, NULL, &data[0], NULL, &status); if (status) throw Common::Exception() << "ffgpxv failed with " << status; std::shared_ptr<IImage> img; switch (bitPixType) { case BYTE_IMG: img = std::make_shared<ImageType<char>>(size, nullptr, channels, 1); break; case SHORT_IMG: img = std::make_shared<ImageType<short>>(size, nullptr, channels, 1); break; case LONG_IMG: img = std::make_shared<ImageType<int>>(size, nullptr, channels, 1); break; case FLOAT_IMG: img = std::make_shared<ImageType<float>>(size, nullptr, channels, 1); break; case DOUBLE_IMG: img = std::make_shared<ImageType<double>>(size, nullptr, channels, 1); break; default: throw Common::Exception() << "uncoded read type " << bitPixType; } memcpy(img->getData(), &data[0], numPixels * bytesPerPixel); ffclos(fitsFilePtr, &status); if (status) throw Common::Exception() << "ffclos failed with " << status; return img; }