summaryrefslogtreecommitdiffstats
path: root/fitsy++/hdu.C
diff options
context:
space:
mode:
Diffstat (limited to 'fitsy++/hdu.C')
-rw-r--r--fitsy++/hdu.C323
1 files changed, 323 insertions, 0 deletions
diff --git a/fitsy++/hdu.C b/fitsy++/hdu.C
new file mode 100644
index 0000000..a3b3b4d
--- /dev/null
+++ b/fitsy++/hdu.C
@@ -0,0 +1,323 @@
+// Copyright (C) 1999-2018
+// Smithsonian Astrophysical Observatory, Cambridge, MA, USA
+// For conditions of distribution and use, see copyright notice in "copyright"
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+using namespace std;
+
+#include "hdu.h"
+#include "head.h"
+#include "util.h"
+
+FitsHDU::FitsHDU(FitsHead* head)
+{
+ extname_ = dupstr(head->getString("EXTNAME"));
+ // trim any spaces at end
+ if (extname_) {
+ for (int ii=strlen(extname_)-1; ii>=0; ii--) {
+ if (extname_[ii] == ' ')
+ extname_[ii] = '\0';
+ else
+ break;
+ }
+ }
+
+ extver_ = head->getInteger("EXTVER", 1);
+ extlevel_ = head->getInteger("EXTLEVEL", 1);
+
+ bitpix_ = head->getInteger("BITPIX", 0);
+ naxes_ = head->getInteger("NAXIS", 0);
+ if (naxes_>FTY_MAXAXES)
+ naxes_ = FTY_MAXAXES;
+
+ // init naxis_
+ for(int i=0; i<FTY_MAXAXES; i++)
+ naxis_[i] = 0;
+
+ for(int i=0; i<naxes_; i++)
+ naxis_[i] = head->getInteger(keycat("NAXIS",(i+1)), 0);
+
+ // special case: 1D image
+ if (naxis_[0]>0 && naxis_[1]==0)
+ naxis_[1] = 1;
+
+ realbytes_ = 0;
+ heapbytes_ = head->getInteger("PCOUNT",0);
+ allbytes_ = 0;
+ padbytes_ = 0;
+ databytes_ = 0;
+ datablocks_ = 0;
+}
+
+FitsHDU::~FitsHDU()
+{
+ if (extname_)
+ delete [] extname_;
+}
+
+char* FitsHDU::keycat(const char* name, int i)
+{
+ ostringstream str;
+ str << name << i << ends;
+ memcpy(keybuf,str.str().c_str(),str.str().length());
+ return keybuf;
+}
+
+void FitsHDU::updateCards(FitsHead* head)
+{
+ head->setInteger("BITPIX", bitpix_, NULL);
+ head->setInteger("NAXIS", naxes_, NULL);
+
+ for (int i=1; i<=naxes_; i++)
+ head->setInteger(keycat("NAXIS", i), naxis_[i-1], NULL);
+}
+
+// FitsImageHDU
+
+FitsImageHDU::FitsImageHDU(FitsHead* head) : FitsHDU(head)
+{
+ size_t imgpixels = (size_t)naxis_[0]*naxis_[1];
+ imgbytes_ = imgpixels * (abs(bitpix_)/8);
+
+ size_t realpixels;
+ if (naxes_>0) {
+ realpixels = 1;
+ for (int i=0; i<naxes_; i++ )
+ realpixels *= naxis_[i];
+ }
+ else
+ realpixels = 0;
+
+ realbytes_ = realpixels * (abs(bitpix_)/8);
+ allbytes_ = realbytes_ + heapbytes_;
+ datablocks_ = (allbytes_ + (FTY_BLOCK-1))/FTY_BLOCK;
+ databytes_ = datablocks_ * FTY_BLOCK;
+ padbytes_ = databytes_ - allbytes_;
+
+ bzero_ = head->getReal("BZERO", 0.0);
+ bscale_ = head->getReal("BSCALE", 1.0);
+ hasblank_ = head->find("BLANK") ? 1:0;
+ blank_ = head->getInteger("BLANK", 0);
+}
+
+void FitsImageHDU::updateCards(FitsHead* head)
+{
+ FitsHDU::updateCards(head);
+ if (blank_)
+ if (bitpix_ > 0)
+ head->setInteger("BLANK", blank_, NULL);
+
+ if (bzero_)
+ head->setReal("BZERO", bzero_ , 7, NULL);
+ if (bscale_ != 1)
+ head->setReal("BSCALE", bscale_, 7, NULL);
+}
+
+// FitsTableHDU
+
+FitsTableHDU::FitsTableHDU(FitsHead* head) : FitsHDU(head)
+{
+ tfields_ = head->getInteger("TFIELDS", 0);
+ cols_ = NULL;
+
+ // number of rows * width of row in bytes
+ realbytes_ = (size_t)naxis_[0]*naxis_[1];
+ allbytes_ = realbytes_ + heapbytes_;
+ datablocks_ = (allbytes_ + (FTY_BLOCK-1))/FTY_BLOCK;
+ databytes_ = datablocks_ * FTY_BLOCK;
+ padbytes_ = databytes_ - allbytes_;
+}
+
+FitsTableHDU::~FitsTableHDU()
+{
+ if (cols_) {
+ for (int i=0; i<tfields_; i++)
+ if (cols_[i])
+ delete cols_[i];
+
+ delete [] cols_;
+ }
+}
+
+char* FitsTableHDU::list()
+{
+ ostringstream str;
+ for (int i=0; i<tfields_; i++)
+ if (cols_[i])
+ str << cols_[i]->ttype() << ' ';
+ str << ends;
+ return dupstr(str.str().c_str());
+}
+
+FitsColumn* FitsTableHDU::find(const char* name)
+{
+ char* n = toUpper(name);
+ // trim any spaces
+ char* nn = n;
+ while (*nn)
+ nn++;
+ nn--;
+ while (*nn == ' ')
+ *nn-- = '\0';
+
+ for (int i=0; i<tfields_; i++) {
+ if (cols_[i]) {
+
+ char* t = toUpper(cols_[i]->ttype());
+ // trim any spaces
+ char* tt=t;
+ while (*tt)
+ tt++;
+ tt--;
+ while (*tt == ' ')
+ *tt-- = '\0';
+
+ if (!strncmp(n,t,strlen(n)) && strlen(n)==strlen(t)) {
+ delete [] n;
+ delete [] t;
+ return cols_[i];
+ }
+
+ delete [] t;
+ }
+ }
+
+ delete [] n;
+ return NULL;
+}
+
+FitsColumn* FitsTableHDU::find(int i)
+{
+ if (i>=0 && i<tfields_)
+ return cols_[i];
+
+ return NULL;
+}
+
+Vector FitsTableHDU::dimension(const char* name)
+{
+ FitsColumn* col = find(name);
+ return col ? col->dimension() : Vector();
+}
+
+FitsAsciiTableHDU::FitsAsciiTableHDU(FitsHead* head) : FitsTableHDU(head)
+{
+ cols_ = new FitsColumn*[tfields_];
+
+ size_t offset = 0;
+ for (int i=0; i<tfields_; i++) {
+ char* tform = head->getString(keycat("TFORM",i+1));
+ char type = 'F';
+ if (tform) {
+ string x(tform);
+ istringstream str(x);
+ str >> type;
+ }
+
+ switch (type) {
+ case 'A':
+ cols_[i] = new FitsAsciiColumnStr(head, i+1, offset);
+ break;
+ case 'I':
+ cols_[i] = new FitsAsciiColumnT<int>(head, i+1, offset);
+ break;
+ case 'F':
+ cols_[i] = new FitsAsciiColumnT<float>(head, i+1, offset);
+ break;
+ case 'E':
+ cols_[i] = new FitsAsciiColumnT<float>(head, i+1, offset);
+ break;
+ case 'D':
+ cols_[i] = new FitsAsciiColumnT<double>(head, i+1, offset);
+ break;
+ }
+
+ if (cols_[i])
+ offset += cols_[i]->width();
+ }
+}
+
+FitsBinTableHDU::FitsBinTableHDU(FitsHead* head) : FitsTableHDU(head)
+{
+ cols_ = new FitsColumn*[tfields_];
+
+ int offset =0;
+ for (int i=0; i<tfields_; i++) {
+ char* tform = head->getString(keycat("TFORM",i+1));
+ int repeat;
+ char type = 'J';
+ if (tform) {
+ string x(tform);
+ istringstream str(x);
+ if (isalpha(tform[0]))
+ str >> type;
+ else
+ str >> repeat >> type;
+ }
+
+ switch (type) {
+ case 'L':
+ cols_[i] = new FitsBinColumnLogical(head, i+1, offset);
+ break;
+ case 'X':
+ cols_[i] = new FitsBinColumnBit(head, i+1, offset);
+ break;
+ case 'B':
+ cols_[i] = new FitsBinColumnT<unsigned char>(head, i+1, offset);
+ break;
+ case 'I':
+ cols_[i] = new FitsBinColumnT<short>(head, i+1, offset);
+ break;
+ case 'U':
+ cols_[i] = new FitsBinColumnT<unsigned short>(head, i+1, offset);
+ break;
+ case 'J':
+ cols_[i] = new FitsBinColumnT<int>(head, i+1, offset);
+ break;
+ case 'V':
+ cols_[i] = new FitsBinColumnT<unsigned int>(head, i+1, offset);
+ break;
+ case 'K':
+ cols_[i] = new FitsBinColumnT<long long>(head, i+1, offset);
+ break;
+ case 'A':
+ cols_[i] = new FitsBinColumnStr(head, i+1, offset);
+ break;
+ case 'E':
+ cols_[i] = new FitsBinColumnT<float>(head, i+1, offset);
+ break;
+ case 'D':
+ cols_[i] = new FitsBinColumnT<double>(head, i+1, offset);
+ break;
+ case 'C':
+ cols_[i] = NULL;
+ internalError("Fitsy++ hdu single precision complex column type not supported");
+ break;
+ case 'M':
+ cols_[i] = NULL;
+ internalError("Fitsy++ hdu double precision complex column type not supported");
+ break;
+ case 'P':
+ cols_[i] = new FitsBinColumnArrayP(head, i+1, offset);
+ break;
+ case 'Q':
+ cols_[i] = new FitsBinColumnArrayQ(head, i+1, offset);
+ break;
+
+ default:
+ cols_[i] = NULL;
+ internalError("Fitsy++ hdu unknown table column type");
+ break;
+ }
+
+ if (cols_[i])
+ offset += cols_[i]->width();
+ }
+}
+