// Copyright (C) 1999-2017 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include #include #include using namespace std; #include #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 (ptrbitpix() == -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 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 (ptrhdu()); unsigned char* src = (unsigned char*)data(); int size = hdu->imgbytes(); float* dest = new float[size]; for (int ii=0; 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; }