// Copyright (C) 1999-2016 // Smithsonian Astrophysical Observatory, Cambridge, MA, USA // For conditions of distribution and use, see copyright notice in "copyright" #include "map.h" #include "head.h" FitsMap::FitsMap() { mapdata_ = NULL; mapsize_ = 0; } char* FitsMap::enddata() { // return the address of the first data byte pass the end of data return head_ ? (char*)data_+head_->databytes() : NULL; } size_t FitsMap::endsize() { // return the size - (header+data) return head_ ? (mapsize_ - (size_t)((char*)data_+head_->databytes()-mapdata_)) : 0; } void FitsMap::found(char* here) { data_ = here + head_->headbytes(); dataSize_ = mapsize_; dataSkip_ = here - mapdata_ + head_->headbytes(); inherit_ = head_->inherit(); valid_ = 1; } void FitsMap::error() { if (manageHead_ && head_) delete head_; head_ = NULL; if (managePrimary_ && primary_) delete primary_; primary_ = NULL; data_ = NULL; dataSize_ = 0; dataSkip_ = 0; valid_ = 0; } FitsFitsMap::FitsFitsMap(ScanMode mode) { if (!valid_) return; if (mode == EXACT || pExt_ || pIndex_>-1) processExact(); else processRelax(); } void FitsFitsMap::processExact() { // find head and data for specified unit char* here = mapdata_; size_t size = mapsize_; // simple check for fits file if (strncmp(mapdata_,"SIMPLE ",8) && strncmp(mapdata_,"XTENSION",8)) { error(); return; } if (!(pExt_ || (pIndex_>0))) { // we are only looking for a primary image head_ = new FitsHead(here, size, FitsHead::EXTERNAL); if (head_->isValid()) { found(here); return; } } else { // we are looking for an extension // keep the primary header primary_ = new FitsHead(here, size, FitsHead::EXTERNAL); managePrimary_ = 1; if (!primary_->isValid()) { error(); return; } here += primary_->headbytes() + primary_->databytes(); size -= primary_->headbytes() + primary_->databytes(); if (pExt_) { while (size > 0) { head_ = new FitsHead(here, size, FitsHead::EXTERNAL); if (!head_->isValid()) { error(); return; } ext_++; if (head_->extname()) { char* a = toUpper(head_->extname()); char* b = toUpper(pExt_); if (!strncmp(a,b,strlen(b))) { delete [] a; delete [] b; found(here); return; } delete [] a; delete [] b; } here += head_->headbytes() + head_->databytes(); size -= head_->headbytes() + head_->databytes(); delete head_; head_ = NULL; } } else { for (int i=1; i0; i++) { head_ = new FitsHead(here, size, FitsHead::EXTERNAL); if (!head_->isValid()) { error(); return; } ext_++; here += head_->headbytes() + head_->databytes(); size -= head_->headbytes() + head_->databytes(); delete head_; head_ = NULL; } head_ = new FitsHead(here, size, FitsHead::EXTERNAL); if (head_->isValid()) { ext_++; found(here); return; } } } // Must have an error error(); } void FitsFitsMap::processRelax() { char* here = mapdata_; size_t size = mapsize_; // simple check for fits file if (strncmp(mapdata_,"SIMPLE ",8) && strncmp(mapdata_,"XTENSION",8)) { error(); return; } // check to see if there is an image in the primary head_ = new FitsHead(here, size, FitsHead::EXTERNAL); if (head_->isValid() && head_->naxes() > 0 && head_->naxis(0) > 0 && head_->naxis(1) > 0) { found(here); return; } // ok, no image, save primary and lets check extensions here += head_->headbytes() + head_->databytes(); size -= head_->headbytes() + head_->databytes(); primary_ = head_; managePrimary_ = 1; head_ = NULL; while (size > 0) { head_ = new FitsHead(here, size, FitsHead::EXTERNAL); if (!head_->isValid()) { error(); return; } ext_++; // check for image if (head_->isImage()) { found(here); return; } // else, check for compressed image if (head_->isBinTable() && head_->find("ZIMAGE")) { found(here); return; } // else, check for bin table named STDEVT, EVENTS, RAYEVENT if (head_->isBinTable() && head_->extname()) { char* a = toUpper(head_->extname()); if (!strncmp("STDEVT", a, 6) || !strncmp("EVENTS", a, 6) || !strncmp("RAYEVENT", a, 8)) { delete [] a; found(here); return; } } // else, check for bin table with keyword PIXTYPE = 'HEALPIX ' if (head_->isBinTable() && head_->find("PIXTYPE") && (!strncmp(head_->getString("PIXTYPE"),"HEALPIX",4))) { found(here); return; } // else, check for bin table with keyword NSIDE (also HEALPIX) if (head_->isBinTable() && head_->find("NSIDE")) { found(here); return; } here += head_->headbytes() + head_->databytes(); size -= head_->headbytes() + head_->databytes(); delete head_; head_ = NULL; } // did not find anything, bail out error(); } FitsFitsNextMap::FitsFitsNextMap(FitsFile* p) { FitsMap* prev = (FitsMap*)p; primary_ = prev->primary(); managePrimary_ = 0; head_ = prev->head(); manageHead_ = 0; FitsImageHDU* hdu = (FitsImageHDU*)head_->hdu(); data_ = (char*)prev->data() + hdu->imgbytes(); dataSize_ = 0; dataSkip_ = 0; ext_ = prev->ext(); inherit_ = prev->inherit(); byteswap_ = prev->byteswap(); endian_ = prev->endian(); valid_ = 1; pcoord_ = prev->pcoord(); pxvalid_ = prev->pxvalid(); pxmin_ = prev->pxmin(); pxmax_ = prev->pxmax(); pyvalid_ = prev->pyvalid(); pymin_ = prev->pymin(); pymax_ = prev->pymax(); pzvalid_ = prev->pzvalid(); pzmin_ = prev->pzmin(); pzmax_ = prev->pzmax(); pbvalid_ = prev->pbvalid(); pblock_ = prev->pblock(); mapdata_ = prev->mapdata(); mapsize_ = prev->mapsize(); return; } FitsArrMap::FitsArrMap() { if (!valid_) return; // reset valid_ = 0; // check to see if we have a nonzero width, height, and bitpix if (!validParams()) return; // check to see if dimensions equal mapped space if (((size_t)pWidth_*pHeight_*pDepth_*abs(pBitpix_)/8)+pSkip_ > mapsize_) return; // skip to start of data data_ = mapdata_ + pSkip_; dataSize_ = mapsize_; dataSkip_ = pSkip_; // new header head_ = new FitsHead(pWidth_, pHeight_, pDepth_, pBitpix_); if (!head_->isValid()) return; // do we byteswap? setByteSwap(); // made it this far, must be valid valid_ = 1; } FitsNRRDMap::FitsNRRDMap() { if (!valid_) return; // reset valid_ = 0; // header { char buf[1024]; char* dptr = buf; char* sptr = mapdata_; int cnt =0; do { *dptr++ = *sptr++; if (cnt>0 && (*sptr == '\n' && *(sptr-1) == '\n')) { pSkip_ = cnt+2; break; } cnt++; } while (cnt<1024); *dptr = '\0'; string x(buf); istringstream str(x); parseNRRD(str); if (!valid_) return; // reset valid_ =0; } // check to see if we have a nonzero width, height, and bitpix if (!validParams()) return; // skip to start of data data_ = mapdata_ + pSkip_; dataSize_ = mapsize_; dataSkip_ = pSkip_; // new header head_ = new FitsHead(pWidth_, pHeight_, pDepth_, pBitpix_); if (!head_->isValid()) return; // do we byteswap? setByteSwap(); // so far, so good valid_ = 1; } FitsMosaicMap::FitsMosaicMap() { if (!valid_) return; char* here = mapdata_; size_t size = mapsize_; // keep the primary header primary_ = new FitsHead(here, size, FitsHead::EXTERNAL); managePrimary_ = 1; if (!primary_->isValid()) { error(); return; } here += primary_->headbytes() + primary_->databytes(); size -= primary_->headbytes() + primary_->databytes(); // first extension head_ = new FitsHead(here, size, FitsHead::EXTERNAL); if (!head_->isValid()) { error(); return; } ext_++; found(here); } FitsMosaicNextMap::FitsMosaicNextMap(FitsFile* p) { FitsMap* prev = (FitsMap*)p; primary_ = prev->primary(); managePrimary_ = 0; ext_ = prev->ext(); mapdata_ = prev->enddata(); mapsize_ = prev->endsize(); head_ = new FitsHead(mapdata_, mapsize_, FitsHead::EXTERNAL); if (!head_->isValid()) { error(); return; } ext_++; found(mapdata_); }