Commit 72d40208 authored by Robert Butora's avatar Robert Butora
Browse files

vlkb-imcopy: fixes release-resources and too-long headers drop COMMENT and HISTORY cards

parent bf01a083
Loading
Loading
Loading
Loading
+50 −11
Original line number Diff line number Diff line
@@ -88,25 +88,58 @@ void imcopy(std::string filename, int extnum, std::string pixfilter, std::string
      throw runtime_error("fits_open_file " + filename + " failed: " + errmsg);
   }

   /* cfitsio(v4.2.0) manual: 10.2.3 Notes about the stream filetype driver
    *  "-" writes to stdout: but first loads all file into mem
    *  "stream://" keeps NIOBUF=40 buffers, and header must fit into it */
   fits_create_file(&newfptr, "stream://", &status);
   if (status)
   {
      string errmsg{ fitsfiles::cfitsio_errmsg(__FILE__, __LINE__, status) };

      int tstatus = 0;
      fits_close_file(fptr, &tstatus);
      if(tstatus) LOG_STREAM << fitsfiles::cfitsio_errmsg(__FILE__, __LINE__, tstatus) << tstatus<< endl;

      throw runtime_error("fits_open_file to stream failed: " + errmsg);
   }

   /* err codes 1..1000 reserved by cfitsio */
   #define HEADER_TOO_LONG (10000)
   #define MAX_CARD_COUNT (1400)
   /* see notes about stream driver in cfitsio manual */
   fits_copy_image_section2(fptr, newfptr, expr, &status);
   if (status)
   {
      int tstatus = 0;
      fits_close_file(fptr, &tstatus);
      if(tstatus) LOG_STREAM << fitsfiles::cfitsio_errmsg(__FILE__, __LINE__, tstatus) << tstatus<< endl;
      tstatus = 0;
      fits_close_file(newfptr, &tstatus);
      if(tstatus) LOG_STREAM << fitsfiles::cfitsio_errmsg(__FILE__, __LINE__, tstatus) << tstatus<< endl;

      if(status == HEADER_TOO_LONG)
      {
         throw runtime_error("Cutout from " + filename
               + " failed: header is too long. Direct streaming in current build support max "
               + to_string(MAX_CARD_COUNT) + " cards in header.");
      }
      else
      {
         string errmsg{fitsfiles::cfitsio_errmsg(__FILE__, __LINE__, status)};
         throw runtime_error("fits_copy_image_section " + filename
               + " to cut-file with " + string{expr} + " failed: " + errmsg);
      }
   }

   fits_close_file(fptr, &status);
   if (status)
   {
      string errmsg{fitsfiles::cfitsio_errmsg(__FILE__, __LINE__, status)};

      int tstatus = 0;
      fits_close_file(newfptr, &tstatus);
      if(tstatus) LOG_STREAM << fitsfiles::cfitsio_errmsg(__FILE__, __LINE__, tstatus) << tstatus<< endl;

      throw runtime_error("fits_close_file " + filename + " failed: " + errmsg);
   }

@@ -120,20 +153,17 @@ void imcopy(std::string filename, int extnum, std::string pixfilter, std::string


/* ---- version 3.49 ------- */
/*
 * Currently this is a direct copy from cfitsio-lib. It will be modified in two ways:
 * - allow bigger buffer the first row (use sub-cube up to dimension k: volume[1.k] < LIMIT)
 * - duplicate buffer and run reader on parallel-thread to avoid reader-write wait for each other
 */
/* Currently this is a direct copy from cfitsio-lib.
 * Ensures read-by-rows on systems (CentOS7) with old cfitsio lib.
 * Also consider to duplicate the buffer and run reader
 * on parallel-thread to avoid reader-write wait for each other. */
int fits_copy_image_section2(
      fitsfile *fptr,  /* I - pointer to input image */
      fitsfile *newptr,  /* I - pointer to output image */
      char *expr,       /* I - Image section expression    */
      int *status)
{
   /*
      copies an image section from the input file to a new output HDU
      */
   /* copies an image section from the input file to a new output HDU */

   int bitpix, naxis, numkeys, nkey;
   long naxes[] = {1,1,1,1,1,1,1,1,1}, smin, smax, sinc;
@@ -172,12 +202,21 @@ int fits_copy_image_section2(
   /* copy all other non-structural keywords from the input to output file */
   fits_get_hdrspace(fptr, &numkeys, NULL, status);

   int cards_written = 4;
   for (nkey = 4; nkey <= numkeys; nkey++) /* skip the first few keywords */
   {
      fits_read_record(fptr, nkey, card, status);

      /* cfitsio(v4.2.0) manual: 10.2.3 Notes about the stream filetype driver
       * stream:// driver has internal buffer NIOBUF=40 blocks e.g. 1400 cards
       * TYP_COMM_KEY: skip HISTORY COMMENT and empty keys */
      if(numkeys > MAX_CARD_COUNT)
         if (fits_get_keyclass(card) == TYP_COMM_KEY) continue;

      if (fits_get_keyclass(card) > TYP_CMPRS_KEY)
      {
         if(++cards_written > MAX_CARD_COUNT) return(HEADER_TOO_LONG);

         /* write the record to the output file */
         fits_write_record(newptr, card, status);
      }