summaryrefslogtreecommitdiffstats
path: root/fitsy++/savefits.C
diff options
context:
space:
mode:
Diffstat (limited to 'fitsy++/savefits.C')
-rw-r--r--fitsy++/savefits.C358
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;
+}
+