Index: trunk/Mars/mcore/fits.h
===================================================================
--- trunk/Mars/mcore/fits.h	(revision 16414)
+++ trunk/Mars/mcore/fits.h	(revision 16415)
@@ -106,4 +106,5 @@
         size_t num_rows;
         size_t num_cols;
+        size_t total_bytes; // NAXIS1*NAXIS2
 
         struct Column
@@ -254,9 +255,6 @@
             offset(off), isCompressed(false), keys(ParseBlock(vec))
         {
-            if (HasKey("ZTABLE"))
-            if (Check("ZTABLE", 'B', "T"))
-            {
+            if (HasKey("ZTABLE") && Check("ZTABLE", 'B', "T"))
                 isCompressed = true;
-            }
 
             if (!Check("XTENSION", 'T', "BINTABLE") ||
@@ -272,5 +270,7 @@
             if (isCompressed)
             {
-                if (!Check("ZPCOUNT", 'I', "0"))
+                if (!Check("ZNAXIS1", 'I') ||
+                    !Check("ZNAXIS2", 'I') ||
+                    !Check("ZPCOUNT", 'I', "0"))
                     return;
             }
@@ -281,4 +281,5 @@
             }
 
+            total_bytes   = Get<size_t>("NAXIS1")*Get<size_t>("NAXIS2");
             bytes_per_row = isCompressed ? Get<size_t>("ZNAXIS1") : Get<size_t>("NAXIS1");
             num_rows      = isCompressed ? Get<size_t>("ZNAXIS2") : Get<size_t>("NAXIS2");
@@ -467,4 +468,35 @@
             return it==cols.end() ? 0 : it->second.num;
         }
+
+        // There may be a gap between the main table and the start of the heap:
+        // this computes the offset
+        streamoff GetHeapShift() const
+        {
+            if (!HasKey("THEAP"))
+                return 0;
+
+            const streamoff shift = Get<streamoff>("THEAP");
+            return shift <= total_bytes ? 0 : shift - total_bytes;
+        }
+
+        // return total number of bytes 'all inclusive'
+        streamoff GetTotalBytes() const
+        {
+            //get offset of special data area from start of main table
+            const streamoff shift = GetHeapShift();
+
+            //and special data area size
+            const streamoff size  = HasKey("PCOUNT") ? Get<streamoff>("PCOUNT") : 0;
+
+            // Get the total size
+            const streamoff total = total_bytes + size + shift;
+
+            // check for padding
+            if (total%2880==0)
+                return total;
+
+            // padding necessary
+            return total + (2880 - (total%2880));
+        }
     };
 
@@ -534,10 +566,10 @@
         // Make sure that no empty vector is returned
         if (endtag && vec.size()%36==0)
-            vec.push_back(string("END     = '' / "));
+            vec.emplace_back("END     = '' / ");
 
         return endtag==2;
     }
 
-    string Compile(const string &key, int16_t i=-1)
+    string Compile(const string &key, int16_t i=-1) const
     {
         if (i<0)
@@ -549,47 +581,5 @@
     }
 
-    //There may be a gap between the main table and the start of the heap: this computes the offset
-    size_t ComputeGapFromDataToHeap(const Table& table)
-    {
-        //get row width
-        const size_t rowWidth = table.Get<size_t>("NAXIS1");
-        const size_t numRows  = table.Get<size_t>("NAXIS2");
-
-        //get offset of special data area from start of main table
-        size_t heapShift = HasKey("THEAP") ? table.Get<size_t>("THEAP") : 0;
-        if (heapShift > rowWidth*numRows)
-            heapShift -= rowWidth*numRows;
-        else
-            heapShift = 0;
-
-        return heapShift;
-    }
-
-    //skip the current table
-    bool SkipCurrentTable(const vector<string>& vector)
-    {
-        Table currentTable(vector, tellg());
-        //get row width
-        const size_t rowWidth = currentTable.Get<size_t>("NAXIS1");
-        const size_t numRows  = currentTable.Get<size_t>("NAXIS2");
-        const off_t  numTableBytes = rowWidth*numRows;
-
-        //get offset of special data area from start of main table
-        const off_t heapShift = ComputeGapFromDataToHeap(currentTable);
-
-        //and special data area size
-        const off_t heapSize  = HasKey("PCOUNT") ? currentTable.Get<off_t>("PCOUNT") : 0;
-
-        //skip the row of the table, padded to 2880 bytes
-        off_t paddingSize     = (rowWidth*numRows + heapSize + heapShift)%2880;
-        paddingSize += (paddingSize==0) ? 0 : 2880 - paddingSize;
-
-        const off_t whereDoIGo = tellg() + numTableBytes + heapSize + heapShift + paddingSize;
-        seekg(whereDoIGo);
-
-        return good();
-    }
-
-    void Constructor(const string &fname, string fout, const string& tableName, bool force, bool mightFail)
+    void Constructor(const string &fname, string fout, const string& tableName, bool force)
     {
         char simple[10];
@@ -616,11 +606,15 @@
             while (1)
             {
+                // If we search for a table, we implicitly assume that
+                // not finding the table is not an error. The user
+                // can easily check that by eof() && !bad()
+                peek();
+                if (eof() && !bad() && !tableName.empty())
+                    break;
+
                 // FIXME: Set limit on memory consumption
                 const int rc = ReadBlock(block);
                 if (!good())
                 {
-                    //we allow that the table is not found (to be checked later on with bool casting)
-                    if (mightFail) { return;}
-
                     clear(rdstate()|ios::badbit);
 #ifdef __EXCEPTIONS
@@ -648,5 +642,5 @@
             }
 
-            if (block.size()==0)
+            if (block.empty())
                 break;
 
@@ -659,20 +653,6 @@
             if (block[0].substr(0, 9)=="XTENSION=")
             {
-                //Check for table name. Skip until eof or requested table are found.
-                if (tableName != "")
-                {
-                    Table currentTable(block, tellg());
-                    string currentName = currentTable.Get<string>("EXTNAME");
-                    if (currentName != tableName)
-                    {
-                        SkipCurrentTable(block);
-                        fChkHeader.reset();
-                        continue;
-                    }
-                }
                 fTable = Table(block, tellg());
                 fRow   = (size_t)-1;
-
-                //fTable.PrintKeys();
 
                 if (!fTable)
@@ -682,19 +662,20 @@
                 }
 
+                //Check for table name. Skip until eof or requested table are found.
+                // skip the current table?
+                if (!tableName.empty() && tableName!=fTable.Get<string>("EXTNAME"))
+                {
+                    const streamoff skip = fTable.GetTotalBytes();
+                    seekg(skip, ios_base::cur);
+
+                    fChkHeader.reset();
+
+                    continue;
+                }
+
+                //fTable.PrintKeys();
+
                 fBufferRow.resize(fTable.bytes_per_row + 8-fTable.bytes_per_row%4);
                 fBufferDat.resize(fTable.bytes_per_row);
-
-                /*
-                 // Next table should start at:
-                 const size_t size = fTable.bytes_per_row*fTable.num_rows;
-                 const size_t blks = size/(36*80);
-                 const size_t rest = size%(36*80);
-
-                seekg((blks+(rest>0?1:0))*(36*80), ios::cur);
-                if (!good())
-                     gLog << ___err___ << "File seems to be incomplete (less data than expected from header)." << endl;
-
-                fRow   = fTable.num_rows;
-                 */
 
                 break;
@@ -734,12 +715,12 @@
 
 public:
-    fits(const string &fname, const string& tableName="", bool force=false, bool mightFail=false) : izstream(fname.c_str())
-    {
-        Constructor(fname, "", tableName, force, mightFail);
-    }
-
-    fits(const string &fname, const string &fout, const string& tableName="", bool force=false, bool mightFail=false) : izstream(fname.c_str())
-    {
-        Constructor(fname, fout, tableName, force, mightFail);
+    fits(const string &fname, const string& tableName="", bool force=false) : izstream(fname.c_str())
+    {
+        Constructor(fname, "", tableName, force);
+    }
+
+    fits(const string &fname, const string &fout, const string& tableName, bool force=false) : izstream(fname.c_str())
+    {
+        Constructor(fname, fout, tableName, force);
     }
 
@@ -879,5 +860,5 @@
         {
             ostringstream str;
-            str <<"SetPtrAddress('" << name << "') - Column not found." << endl;
+            str << "SetPtrAddress('" << name << "') - Column not found." << endl;
 #ifdef __EXCEPTIONS
             throw runtime_error(str.str());
@@ -892,10 +873,10 @@
             return it->second;
 
-        fGarbage.push_back(vector<char>(fTable.cols[name].size*fTable.cols[name].num));
+        fGarbage.emplace_back(fTable.cols[name].size*fTable.cols[name].num);
 
         void *ptr = fGarbage.back().data();
 
         fPointers[name] = ptr;
-        fAddresses.push_back(make_pair(ptr, fTable.cols[name]));
+        fAddresses.emplace_back(ptr, fTable.cols[name]);
         sort(fAddresses.begin(), fAddresses.end(), Compare);
         return ptr;
@@ -948,5 +929,5 @@
         //fAddresses[ptr] = fTable.cols[name];
         fPointers[name] = ptr;
-        fAddresses.push_back(make_pair(ptr, fTable.cols[name]));
+        fAddresses.emplace_back(ptr, fTable.cols[name]);
         sort(fAddresses.begin(), fAddresses.end(), Compare);
         return true;
@@ -996,5 +977,5 @@
         //fAddresses[ptr] = fTable.cols[name];
         fPointers[name] = ptr;
-        fAddresses.push_back(make_pair(ptr, fTable.cols[name]));
+        fAddresses.emplace_back(ptr, fTable.cols[name]);
         sort(fAddresses.begin(), fAddresses.end(), Compare);
         return true;
