252 ofstream fout(ofile);
256 fin.read((
char*)m, 2);
257 if (m[0]!=
'z'+128 || m[1]!=
'f'+128)
258 throw runtime_error(
"File not a compressed fits file.");
262 fin.read((
char*)&hlen,
sizeof(
size_t));
264 throw runtime_error(
"Only Version-zero files supported.");
268 fin.read((
char*)&hs,
sizeof(
size_t));
270 throw runtime_error(
"Could not access header size.");
277 fin.read((
char*)header.c_str(), header.size());
278 fout.write((
char*)header.c_str(), header.size());
280 throw runtime_error(
"Could not read full header");
282 string templ(
"tmpXXXXXX");
283 int fd = mkstemp((
char*)templ.c_str());
284 const ssize_t rc = write(fd, header.c_str(), header.size());
288 throw runtime_error(
"Could not write to temporary file: "+
string(strerror(errno)));
293 remove(templ.c_str());
299 map<size_t, fits::Table::Column> columns;
300 for (
auto it=cols.begin(); it!=cols.end(); it++)
302 columns[it->second.offset] = it->second;
303 row_tot += it->second.num*it->second.size;
310 size_t com = 2+hs+2*
sizeof(size_t);
313 const size_t masklen = cols.size()/8+1;
316 vector<char> buf(row_tot+masklen);
317 vector<char> swap(row_tot);
320 const uint64_t nrows = info.GetUInt(
"NAXIS2");
325 for (uint32_t irow=0; irow<nrows; irow++)
327 fin.read(buf.data()+offset, buf.size()-offset);
329 const uint8_t *mask =
reinterpret_cast<uint8_t*
>(buf.data());
332 char *ptr = swap.data();
335 for (
auto it=columns.begin(); it!= columns.end(); it++, icol++)
337 const size_t &num = it->second.num;
338 const size_t &
size = it->second.size;
340 if (mask[icol/8]&(1<<(icol%8)))
344 vector<uint16_t> out(num*size/2);
345 int len =
Huffman::Decode((uint8_t*)buf.data()+offset, buf.size()-offset, out);
347 throw runtime_error(
"Decoding failed.");
353 revcpy<2>(ptr, (
char*)out.data(), num);
359 case 1: memcpy (ptr, buf.data()+offset, num*
size);
break;
360 case 2: revcpy<2>(ptr, buf.data()+offset, num);
break;
361 case 4: revcpy<4>(ptr, buf.data()+offset, num);
break;
362 case 8: revcpy<8>(ptr, buf.data()+offset, num);
break;
371 com += offset+masklen;
374 fout.write((
char*)swap.data(), swap.size());
376 memmove(buf.data(), buf.data()+offset, buf.size()-offset);
377 offset = buf.size()-offset;
380 throw runtime_error(
"Error writing to output file");
382 const float proc = float(irow)/nrows;
386 cout <<
"\r" << setprecision(0) << setw(3) << 100*proc <<
"% [" << setprecision(1) << setw(5) << 100.*com/tot <<
"%] cpu:" << sec <<
"s out:" << tot/1000000/elep <<
"MB/s" << flush;
392 cout << setprecision(0) <<
"\r100% [" << setprecision(1) << setw(5) << 100.*com/tot <<
"%] cpu:" << sec <<
"s out:" << tot/1000000/elep <<
"MB/s" << endl;
std::map< std::string, Column > Columns
Adds some functionality to boost::posix_time::ptime for our needs.
int64_t Decode(const uint8_t *bufin, size_t bufinlen, std::vector< uint16_t > &pbufout)