diff options
Diffstat (limited to 'fitsy/savefits.C')
-rw-r--r-- | fitsy/savefits.C | 358 |
1 files changed, 358 insertions, 0 deletions
diff --git a/fitsy/savefits.C b/fitsy/savefits.C new file mode 100644 index 0000000..bfd6f94 --- /dev/null +++ b/fitsy/savefits.C @@ -0,0 +1,358 @@ +// Copyright (C) 1999-2018 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#include <iostream> +#include <sstream> +#include <iomanip> +using namespace std; + +#include <tcl.h> + +#include "file.h" +#include "util.h" +#include "outfile.h" +#include "outchannel.h" +#include "outsocket.h" + +int FitsFile::saveFitsPrimHeader(OutFitsStream& str) +{ + // write fake primary header + char buf[FTY_BLOCK]; + memset(buf,' ',FTY_BLOCK); + + char* hdu = buf; + + memcpy(hdu,"SIMPLE = ",10); + memcpy(hdu+32-3,"T /",3); + hdu += FTY_CARDLEN; + + memcpy(hdu,"BITPIX = ",10); + memcpy(hdu+32-3,"8 /",3); + hdu += FTY_CARDLEN; + + memcpy(hdu,"NAXIS = ",10); + memcpy(hdu+32-3,"0 /",3); + hdu += FTY_CARDLEN; + + memcpy(hdu,"END",3); + str.write(buf, FTY_BLOCK); + + return FTY_BLOCK; +} + +int FitsFile::saveFitsHeaderCards(OutFitsStream& str, int depth, int cc) +{ + char buf[FTY_CARDLEN]; + int cnt = 0; + + char* ptr = head()->cards() + cc; + char* end = head()->cards() + head()->headbytes(); + + while (ptr<end) { + if (!strncmp(ptr,"BITPIX",6) && head()->bitpix() == -16) { + memset(buf,' ',FTY_CARDLEN); + memcpy(buf,"BITPIX = ",10); + memcpy(buf+32-4,"32 /",4); + str.write(buf, FTY_CARDLEN); + } + else if (!strncmp(ptr,"NAXIS ",6)) { + memset(buf,' ',FTY_CARDLEN); + memcpy(buf,"NAXIS = ",10); + if (depth>1) + memcpy(buf+32-3,"3 /",3); + else + if (head()->naxis(1)>1) + memcpy(buf+32-3,"2 /",3); + else + memcpy(buf+32-3,"1 /",3); + str.write(buf, FTY_CARDLEN); + } + else if (!strncmp(ptr,"NAXIS2",6)) { + str.write(ptr, FTY_CARDLEN); + + if (depth>1) { + ostringstream ddstr; + ddstr << depth << " /" << ends; + const char* ddptr = dupstr(ddstr.str().c_str()); + int ll = strlen(ddptr); + + memset(buf,' ',FTY_CARDLEN); + memcpy(buf,"NAXIS3 = ",10); + memcpy(buf+32-ll, ddptr, ll); + str.write(buf, FTY_CARDLEN); + cnt += FTY_CARDLEN; + delete [] ddptr; + } + } + else if (!strncmp(ptr,"NAXIS3",6)) { + // skip, we already take care of it above + cnt -= FTY_CARDLEN; + } + else if (!strncmp(ptr,"NAXIS4",6)) { + // skip, better not be here + cnt -= FTY_CARDLEN; + } + else if (!strncmp(ptr,"NAXIS5",6)) { + // skip, better not be here + cnt -= FTY_CARDLEN; + } + else if (!strncmp(ptr,"PCOUNT",6)) { + // skip + cnt -= FTY_CARDLEN; + } + else if (!strncmp(ptr,"GCOUNT",6)) { + // skip + cnt -= FTY_CARDLEN; + } + else if (!strncmp(ptr,"END ",6)) { + // skip, will insert at the end + cnt -= FTY_CARDLEN; + } + else if (!strncmp(ptr,"CRVAL3",6) && depth==1) + // skip + cnt -= FTY_CARDLEN; + else if (!strncmp(ptr,"CRPIX3",6) && depth==1) + // skip + cnt -= FTY_CARDLEN; + else if (!strncmp(ptr,"CDELT3",6) && depth==1) + // skip + cnt -= FTY_CARDLEN; + else if (!strncmp(ptr,"CTYPE3",6) && depth==1) + // skip + cnt -= FTY_CARDLEN; + else if (!strncmp(ptr,"CUNIT3",6) && depth==1) + // skip + cnt -= FTY_CARDLEN; + else if (!strncmp(ptr,"CD3_",4) && depth==1) + // skip + cnt -= FTY_CARDLEN; + else if (!strncmp(ptr,"PC3_",4) && depth==1) + // skip + cnt -= FTY_CARDLEN; + else + str.write(ptr, FTY_CARDLEN); + + ptr += FTY_CARDLEN; + cnt += FTY_CARDLEN; + } + + // final END + memset(buf,' ',FTY_CARDLEN); + memcpy(buf,"END",3); + str.write(buf, FTY_CARDLEN); + cnt += FTY_CARDLEN; + + return cnt; +} + +int FitsFile::saveFitsHeader(OutFitsStream& str, int depth) +{ + int cnt =0; + char buf[FTY_CARDLEN]; + + memset(buf,' ',FTY_CARDLEN); + memcpy(buf,"SIMPLE = ",10); + memcpy(buf+32-3,"T /",3); + str.write(buf, FTY_CARDLEN); + cnt += FTY_CARDLEN; + + cnt += saveFitsHeaderCards(str,depth,cnt); + cnt += saveFitsPad(str,cnt,' '); + + return cnt; +} + +int FitsFile::saveFitsXtHeader(OutFitsStream& str, int depth) +{ + // write xtension header + // the header may be an xtension, or primary, so lets force a + // first line of 'SIMPLE' and then write the rest of the header + int cnt =0; + char buf[FTY_CARDLEN]; + + memset(buf,' ',FTY_CARDLEN); + memcpy(buf,"XTENSION= 'IMAGE '",20); + str.write(buf, FTY_CARDLEN); + cnt += FTY_CARDLEN; + + cnt += saveFitsHeaderCards(str,depth,cnt); + cnt += saveFitsPad(str,cnt,' '); + + return cnt; +} + +int FitsFile::saveFits(OutFitsStream& str) +{ + FitsImageHDU* hdu = (FitsImageHDU*)(head()->hdu()); + + if (hdu->bitpix() != -16) { + switch (endian_) { + case BIG: + str.write((char*)data(), hdu->imgbytes()); + break; + case LITTLE: + str.writeSwap((char*)data(), hdu->imgbytes(), head()->bitpix()); + break; + case NATIVE: + break; + } + + return hdu->imgbytes(); + } + + // convert bitpix=-16 to bitpix=32 + int nx = head()->naxis(0); + int ny = head()->naxis(1); + int ss = nx*ny; + int* dest = new int[ss]; + for(int jj=0; jj<ny; jj++) { + for (int ii=0; ii<nx; ii++) { + unsigned short* data = (unsigned short*)data_; + unsigned short* ptr = data + jj*nx +ii; + + unsigned short vv; + if (byteswap_) + swap2((char*)ptr, (char*)&vv); + else + vv = *ptr; + + dest[jj*nx + ii] = int(vv); + } + } + + if (!lsb()) + str.write((char*)dest, 4*ss); + else + str.writeSwap((char*)dest, 4*ss, 32); + + delete [] dest; + return 4*ss; +} + +int FitsFile::saveFitsPad(OutFitsStream& str, size_t cnt, char fil) +{ + // write any padding + char buf[FTY_BLOCK]; + memset(buf,fil,FTY_BLOCK); + + int npad = FTY_BLOCK - (cnt % FTY_BLOCK); + if (npad == FTY_BLOCK) + npad = 0; + if( npad > 0 ) + str.write(buf, npad); + + return npad; +} + +int FitsFile::saveFitsTable(OutFitsStream& str) +{ + int cnt =0; + // primary header + str.write(primary()->cards(), primary()->headbytes()); + cnt += primary()->headbytes(); + + // now, ext header + str.write(head()->cards(), head()->headbytes()); + cnt += head()->headbytes(); + + // write valid data + // our data may be short (mmap or bad fits), so write valid data + // then write the pad, becareful with arch, if array + + switch (endian_) { + case BIG: + str.write((char*)data(), head()->allbytes()); + break; + case LITTLE: + str.writeSwap((char*)data(), head()->allbytes(), head()->bitpix()); + break; + case NATIVE: + break; + } + cnt += head()->allbytes(); + + // we may need to add a buffer to round out to block size + int diff = head()->padbytes(); + if (diff>0) { + char* buf = new char[diff]; + memset(buf,'\0',diff); + str.write(buf, diff); + delete [] buf; + } + cnt += head()->padbytes(); + + return cnt; +} + +int FitsFile::saveFitsIISHeader(OutFitsStream& str) +{ + int cnt =0; + char buf[FTY_CARDLEN]; + + char* ptr = head()->cards(); + char* end = head()->cards() + head()->headbytes(); + while (ptr<end) { + if (!strncmp(ptr,"BITPIX",6)) { + memset(buf,' ',FTY_CARDLEN); + memcpy(buf,"BITPIX = ",10); + memcpy(buf+32-4,"-32 /",5); + str.write(buf, FTY_CARDLEN); + } + else + str.write(ptr, FTY_CARDLEN); + + ptr+=FTY_CARDLEN; + cnt += FTY_CARDLEN; + } + + cnt += saveFitsPad(str,cnt,' '); + + return cnt; +} + +int FitsFile::saveFitsIIS(OutFitsStream& str, Vector& iisz) +{ + FitsImageHDU* hdu = (FitsImageHDU*)(head()->hdu()); + + unsigned char* src = (unsigned char*)data(); + int size = hdu->imgbytes(); + float* dest = new float[size]; + + for (int ii=0; ii<size; ii++) + if (src[ii] == 0) + dest[ii] = NAN; + else if (src[ii] == 1) + dest[ii] = iisz[0]; + else if (src[ii] == 200) + dest[ii] = iisz[1]; + else if (src[ii] > 200) + dest[ii] = NAN; + else + dest[ii] = ((src[ii]-1) * (iisz[1]-iisz[0]))/199 + iisz[0]; + + if (!lsb()) + str.write((char*)dest, size*sizeof(float)); + else + str.writeSwap((char*)dest, size*sizeof(float), -32); + + if (dest) + delete [] dest; + + return size*sizeof(float); +} + +int FitsFile::saveArray(OutFitsStream& str, ArchType which) +{ + // only save one slice + size_t size = head_->naxis(0)*head_->naxis(1)*abs(head_->bitpix()/8); + int bitpix = head_->bitpix(); + + if (which == endian_) + str.write((char*)data(), size); + else + str.writeSwap((char*)data(), size, bitpix); + + return size; +} + |