int fitscopy ( char *infile, char *outfile) 
{
	fitsfile *infptr, *outfptr;   /* FITS file pointers defined in fitsio.h */
	int status = 0, ii = 1;       /* status must always be initialized = 0  */

	/* Open the input file */
	if ( !fits_open_file(&infptr, infile, READONLY, &status) )
	{
		/* Create the output file */
		if ( !fits_create_file(&outfptr, outfile, &status) )
		{
			/* Copy every HDU until we get an error */
			while( !fits_movabs_hdu(infptr, ii++, NULL, &status) )
				fits_copy_hdu(infptr, outfptr, 0, &status);
 
			/* Reset status after normal error */
			if (status == END_OF_FILE) status = 0;

			fits_close_file(outfptr,  &status);
		}
		fits_close_file(infptr, &status);
	}

	/* if error occured, print out error message */
	if (status) fits_report_error(stderr, status);
	return(status);
}
Beispiel #2
0
int main(int argc, char *argv[])
{
    fitsfile *infptr, *outfptr;
    int status = 0, hdutype, ii;
    char infile[FLEN_FILENAME],outfile[FLEN_FILENAME]; 

    if (argc != 3)
    {
        printf("Usage: fitscopy inputfile outputfile\n");
        return(1);
    }

    strcpy(infile,  argv[1] );  
    strcpy(outfile, argv[2] );  

    if ( fits_open_file(&infptr, infile, READONLY, &status) )
    {
         fits_report_error(stderr, status);
         return(status);
    }

    if ( fits_create_file(&outfptr, outfile, &status) )
    {
         fits_close_file(infptr, &status);
         fits_report_error(stderr, status);
         return(status);
    }

    /* attempt to move to next HDU, until we get an EOF error */
    for (ii = 1; !(fits_movabs_hdu(infptr, ii, &hdutype, &status) ); ii++) 
    {
        if ( fits_copy_hdu(infptr, outfptr, 0, &status) )
        {
            fits_report_error(stderr, status);
            break;
        }
    }

    if (status == END_OF_FILE)   
        status = 0;              /* got the expected EOF error; reset = 0  */

    fits_close_file(infptr,  &status);
    fits_close_file(outfptr, &status);

    if (status)
        fits_report_error(stderr, status);

    return(0);
}
Beispiel #3
0
static void
fits_hdu_copy(struct fitsparams *p, int cut1_copy0, int *r)
{
  char *hdu;
  fitsfile *in, *out;
  int status=0, hdutype;
  gal_list_str_t *list = cut1_copy0 ? p->cut : p->copy;

  /* Open the output file. */
  out=gal_fits_open_to_write(p->cp.output);

  /* Copy all the given extensions. */
  while(list)
    {
      /* Pop-out the top element. */
      hdu=gal_list_str_pop(&list);

      /* Open the FITS file at the specified HDU. */
      in=gal_fits_hdu_open(p->filename, hdu,
                           cut1_copy0 ? READWRITE : READONLY);

      /* Copy to the extension. */
      if( fits_copy_hdu(in, out, 0, &status) )
        *r=fits_has_error(p, FITS_ACTION_COPY, hdu, status);

      /* If this is a `cut' operation, then remove the extension. */
      if(cut1_copy0)
        if( fits_delete_hdu(in, &hdutype, &status) )
          *r=fits_has_error(p, FITS_ACTION_REMOVE, hdu, status);

      /* Close the input file. */
      fits_close_file(in, &status);
    }

  /* Close the output file. */
  fits_close_file(out, &status);
}
int main(int argc, char *argv[])
{

    static struct option long_opts[] = {
        {"start",  1, NULL, 's'},
        {"end",    1, NULL, 'e'},
	{0,0,0,0}
    };	

    fitsfile *infptr, *outfptr;   /* FITS file pointers defined in fitsio.h */
    int opt, opti;
    int i, status = 0, ii = 1, jj=1;       /* status must always be initialized = 0  */
    int lo_row, hi_row;
    unsigned char *buffer = 0;

    long nrows;
    int ncols;
    int tfields;
    long  pcount;
    char  extname[FLEN_VALUE];
    char  *ttype[NFIELDS_I];
    char  *tform[NFIELDS_I];
    char  *tunit[NFIELDS_I];
    char  *tcomm[NFIELDS_I];

    float start=0.0, end=1.0;
    while ((opt=getopt_long(argc,argv,"s:e:h",long_opts,&opti))!=-1) {
        switch (opt) {
	    case 's':
	        start = atof(optarg);
		break;
	    case 'e':
	        end = atof(optarg);
		break;
	    case 'h':
	    default:
	        usage();
		exit(0);
		break;
	}	

    }

    if (argc < 3)
    {
      usage();
      return(0);
    }

    //printf("> %s %s\n", argv[1], argv[2]);
    //printf("> %s %s\n", argv[optind], argv[2]);


   /* Allocate space for the table parameters and initialize */
   for (i=0; i<NFIELDS_I; i++)
   {
      ttype[i] = (char *) malloc(FLEN_VALUE*sizeof(char));
      tform[i] = (char *) malloc(FLEN_VALUE*sizeof(char));
      tunit[i] = (char *) malloc(FLEN_VALUE*sizeof(char));
      tcomm[i] = (char *) malloc(FLEN_CARD*sizeof(char));
      strcpy(ttype[i], " ");
   }


    /* Open the input file */
    if ( !fits_open_file(&infptr, argv[optind], READONLY, &status) )
    {
      /* Create the output file */
      if ( !fits_create_file(&outfptr, argv[optind+1], &status) )
      {
        /* Copy every HDU until we get an error */
        //while( !fits_movabs_hdu(infptr, ii++, NULL, &status) )
	
	/* Copy first HDU */
        fits_copy_hdu(infptr, outfptr, 0, &status);

	fits_movnam_hdu(infptr, BINARY_TBL, "SUBINT", 0, &status);

	fits_get_num_rows(infptr, &nrows, &status);
	printf("Number of rows = %ld\n", nrows);
	
	fits_get_num_cols(infptr, &ncols, &status);
	printf("Number of cols = %d\n", ncols);
		
	long width;
	fits_read_key(infptr, TLONG, "NAXIS1", &width, NULL, &status);
	printf("Width = %ld\n", width);
	buffer = (unsigned char *) malloc(width);
	
	/* Copy the fits header */
	fits_copy_header(infptr, outfptr, &status);

//#if 0
	/* Determine low and high row number ot copy */
	lo_row = 1 + start * nrows;
	hi_row = end * nrows;
	printf("lo_row=%d hi_row=%d\n", lo_row, hi_row);

	for (ii=lo_row, jj=1; ii<=hi_row; ii++, jj++) {
	    printf("\rRead %d/%ld", ii, nrows);
	    fits_read_tblbytes( infptr,  ii, 1, width, buffer, &status);

	    fits_write_tblbytes(outfptr, jj, 1, width, buffer, &status);
	}
	nrows = (hi_row-lo_row)+1;
	fits_update_key(outfptr, TLONG, "NAXIS2", &nrows, 0, &status);
	printf("\nDone\n");
//#endif
        /* Reset status after normal error */
        //if (status == END_OF_FILE) status = 0;

        fits_close_file(outfptr,  &status);
      }
      fits_close_file(infptr, &status);
    }

    /* if error occured, print out error message */
    if (status) fits_report_error(stderr, status);
    return(status);
}
Beispiel #5
0
int main(int argc, char *argv[])
{
  fitsfile *infptr = 0, *outfptr = 0;  /* FITS file pointers */
  int status = 0;   /* CFITSIO status value MUST be initialized to zero! */
  int hdutype = 0, hdunum = 0, ii = 0;

  int printhelp = (argc == 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0));

  if (printhelp || argc != 4) {
    fprintf(stderr, "Usage:  %s infile expression outfile\n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "Copy selected rows from the input table to the output file\n");
    fprintf(stderr, "based on the input boolean expression.  The expression may \n");
    fprintf(stderr, "be a function of the values in other table columns or header \n");
    fprintf(stderr, "keyword values.  If the expression evaluates to 'true' then \n");
    fprintf(stderr, "that row is copied to the output file.\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "Example: \n");
    fprintf(stderr, "1. %s intab.fits+1 'counts > 0' outab.fits\n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "    copy rows that have a positive 'counts' column value\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "2. %s intab.fits+1 'gtifilter()' outab.fits\n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "    Select rows which have a Time column value that is\n");
    fprintf(stderr, "    within one of the Good Time Intervals (GTI) which are\n");
    fprintf(stderr, "    defined in a separate GTI extension in the same file.\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "3. %s intab.fits+1 'regfilter(\"pow.reg\")' outab.fits\n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "    Select rows which have X,Y column coordinates located\n");
    fprintf(stderr, "    within the spatial region defined in the file named\n");
    fprintf(stderr, "    'pow.reg'.  This is an ASCII text file containing a\n");
    fprintf(stderr, "    list of one or more geometric regions such as circle,\n");
    fprintf(stderr, "    rectangle, annulus, etc.\n");
    return (0);
  }
  if (!fits_open_file(&infptr, argv[1], READONLY, &status)) {
    if (fits_get_hdu_type(infptr, &hdutype,&status) ||
        hdutype==IMAGE_HDU) {
      fprintf(stderr, "Error: input HDU is not a table\n");
    } else {

      fits_get_hdu_num(infptr, &hdunum);  /* save current HDU location */

      if (!fits_create_file(&outfptr, argv[3], &status)) {
        /* copy all the HDUs from the input file to the output file */
        for (ii = 1; !status; ii++) {
          if (!fits_movabs_hdu(infptr, ii, NULL, &status)) {
            fits_copy_hdu(infptr, outfptr, 0, &status);
          }
        }

        if (status == END_OF_FILE) {
          status = 0;  /* reset expected error */
        }

        /* move back to initial position in the file */
        fits_movabs_hdu(outfptr, hdunum, NULL, &status);

        /* argv[2] is the expression */
        /* input and output files are the same, so delete rows that */
        /* do not satisfy the expression */
        fits_select_rows(outfptr, outfptr, argv[2], &status);

        fits_close_file(outfptr, &status);  /* Done */
      }
    }
    fits_close_file(infptr, &status);
  }

  if (status) {
    fits_report_error(stderr, status);  /* print any error message */
  }
  return (status);
}
Beispiel #6
0
int main(int argc, char *argv[])
{
    fitsfile *infptr, *outfptr;   /* FITS file pointers defined in fitsio.h */
    int status = 0, ii = 1, iteration = 0, single = 0, hdupos;
    int hdutype, bitpix, bytepix, naxis = 0, nkeys, datatype = 0, anynul;
    long naxes[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1};
    long first, totpix = 0, npix;
    double *array, bscale = 1.0, bzero = 0.0, nulval = 0.;
    char card[81];

    if (argc != 3)
    {
 printf("\n");
 printf("Usage:  imcopy inputImage outputImage[compress]\n");
 printf("\n");
 printf("Copy an input image to an output image, optionally compressing\n");
 printf("or uncompressing the image in the process.  If the [compress]\n");
 printf("qualifier is appended to the output file name then the input image\n");
 printf("will be compressed using the tile-compressed format.  In this format,\n");
 printf("the image is divided into rectangular tiles and each tile of pixels\n");
 printf("is compressed and stored in a variable-length row of a binary table.\n");
 printf("If the [compress] qualifier is omitted, and the input image is\n");
 printf("in tile-compressed format, then the output image will be uncompressed.\n");
 printf("\n");
 printf("If an extension name or number is appended to the input file name, \n");
 printf("enclosed in square brackets, then only that single extension will be\n");
 printf("copied to the output file.  Otherwise, every extension in the input file\n");
 printf("will be processed in turn and copied to the output file.\n");
 printf("\n");
 printf("Examples:\n");
 printf("\n");
 printf("1)  imcopy image.fit 'cimage.fit[compress]'\n");
 printf("\n");
 printf("    This compresses the input image using the default parameters, i.e.,\n");
 printf("    using the Rice compression algorithm and using row by row tiles.\n");
 printf("\n");
 printf("2)  imcopy cimage.fit image2.fit\n");
 printf("\n");
 printf("    This uncompress the image created in the first example.\n");
 printf("    image2.fit should be identical to image.fit if the image\n");
 printf("    has an integer datatype.  There will be small differences\n");
 printf("    in the pixel values if it is a floating point image.\n");
 printf("\n");
 printf("3)  imcopy image.fit 'cimage.fit[compress GZIP 100,100;4]'\n");
 printf("\n");
 printf("    This compresses the input image using the following parameters:\n");
 printf("         GZIP compression algorithm;\n");
 printf("         100 X 100 pixel compression tiles;\n");
 printf("         noise_bits = 4 (only used with floating point images)\n");
 printf("\n");
 printf("The full syntax of the compression qualifier is:\n");
 printf("    [compress ALGORITHM TDIM1,TDIM2,...; NOISE_BITS]\n");
 printf("where the allowed ALGORITHM values are Rice, GZIP, PLIO, \n");
 printf("and TDIMn is the size of the compression tile in each dimension,\n");
 printf("and NOISE_BITS = 1, 2, 3, or 4 and controls the amount of noise\n");
 printf("suppression when compressing floating point images. \n");
 printf("\n");
 printf("Note that it may be necessary to enclose the file names\n");
 printf("in single quote characters on the Unix command line.\n");
      return(0);
    }

    /* Open the input file and create output file */
    fits_open_file(&infptr, argv[1], READONLY, &status);
    fits_create_file(&outfptr, argv[2], &status);

    if (status != 0) {    
        fits_report_error(stderr, status);
        return(status);
    }

    fits_get_hdu_num(infptr, &hdupos);  /* Get the current HDU position */

    /* Copy only a single HDU if a specific extension was given */ 
    if (hdupos != 1 || strchr(argv[1], '[')) single = 1;

    for (; !status; hdupos++)  /* Main loop through each extension */
    {

      fits_get_hdu_type(infptr, &hdutype, &status);

      if (hdutype == IMAGE_HDU) {

          /* get image dimensions and total number of pixels in image */
          for (ii = 0; ii < 9; ii++)
              naxes[ii] = 1;

          fits_get_img_param(infptr, 9, &bitpix, &naxis, naxes, &status);

          totpix = naxes[0] * naxes[1] * naxes[2] * naxes[3] * naxes[4]
             * naxes[5] * naxes[6] * naxes[7] * naxes[8];
      }

      if (hdutype != IMAGE_HDU || naxis == 0 || totpix == 0) { 

          /* just copy tables and null images */
          fits_copy_hdu(infptr, outfptr, 0, &status);

      } else {

          /* Explicitly create new image, to support compression */
          fits_create_img(outfptr, bitpix, naxis, naxes, &status);
          if (status) {
                 fits_report_error(stderr, status);
                 return(status);
          }
	  	    
          /* copy all the user keywords (not the structural keywords) */
          fits_get_hdrspace(infptr, &nkeys, NULL, &status); 

          for (ii = 1; ii <= nkeys; ii++) {
              fits_read_record(infptr, ii, card, &status);
              if (fits_get_keyclass(card) > TYP_CMPRS_KEY)
                  fits_write_record(outfptr, card, &status);
          }

          switch(bitpix) {
              case BYTE_IMG:
                  datatype = TBYTE;
                  break;
              case SHORT_IMG:
                  datatype = TSHORT;
                  break;
              case LONG_IMG:
                  datatype = TINT;
                  break;
              case FLOAT_IMG:
                  datatype = TFLOAT;
                  break;
              case DOUBLE_IMG:
                  datatype = TDOUBLE;
                  break;
          }

          bytepix = abs(bitpix) / 8;

          npix = totpix;
          iteration = 0;

          /* try to allocate memory for the entire image */
          /* use double type to force memory alignment */
          array = (double *) calloc(npix, bytepix);

          /* if allocation failed, divide size by 2 and try again */
          while (!array && iteration < 10)  {
              iteration++;
              npix = npix / 2;
              array = (double *) calloc(npix, bytepix);
          }

          if (!array)  {
              printf("Memory allocation error\n");
              return(0);
          }

          /* turn off any scaling so that we copy the raw pixel values */
          fits_set_bscale(infptr,  bscale, bzero, &status);
          fits_set_bscale(outfptr, bscale, bzero, &status);

          first = 1;
          while (totpix > 0 && !status)
          {
             /* read all or part of image then write it back to the output file */
             fits_read_img(infptr, datatype, first, npix, 
                     &nulval, array, &anynul, &status);

             fits_write_img(outfptr, datatype, first, npix, array, &status);
             totpix = totpix - npix;
             first  = first  + npix;
          }
          free(array);
      }

      if (single) break;  /* quit if only copying a single HDU */
      fits_movrel_hdu(infptr, 1, NULL, &status);  /* try to move to next HDU */
    }

    if (status == END_OF_FILE)  status = 0; /* Reset after normal error */

    fits_close_file(outfptr,  &status);
    fits_close_file(infptr, &status);

    /* if error occurred, print out error message */
    if (status)
       fits_report_error(stderr, status);
    return(status);
}
int main(int argc, char *argv[])
{
  fitsfile *infptr = 0, *outfptr = 0;   /* FITS file pointers defined in fitsio.h */
  int status = 0, ii = 1;       /* status must always be initialized = 0  */

  if (argc != 3) {
    fprintf(stderr, "Usage:  %s inputfile outputfile\n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "Copy an input file to an output file, optionally filtering\n");
    fprintf(stderr, "the file in the process.  This seemingly simple program can\n");
    fprintf(stderr, "apply powerful filters which transform the input file as\n");
    fprintf(stderr, "it is being copied.  Filters may be used to extract a\n");
    fprintf(stderr, "subimage from a larger image, select rows from a table,\n");
    fprintf(stderr, "filter a table with a GTI time extension or a SAO region file,\n");
    fprintf(stderr, "create or delete columns in a table, create an image by\n");
    fprintf(stderr, "binning (histogramming) 2 table columns, and convert IRAF\n");
    fprintf(stderr, "format *.imh or raw binary data files into FITS images.\n");
    fprintf(stderr, "See the CFITSIO User's Guide for a complete description of\n");
    fprintf(stderr, "the Extended File Name filtering syntax.\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "Examples:\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "%s in.fit out.fit                   (simple file copy)\n", argv[0]);
    fprintf(stderr, "%s - -                              (stdin to stdout)\n", argv[0]);
    fprintf(stderr, "%s in.fit[11:50,21:60] out.fit      (copy a subimage)\n", argv[0]);
    fprintf(stderr, "%s iniraf.imh out.fit               (IRAF image to FITS)\n", argv[0]);
    fprintf(stderr, "%s in.dat[i512,512] out.fit         (raw array to FITS)\n", argv[0]);
    fprintf(stderr, "%s in.fit[events][pi>35] out.fit    (copy rows with pi>35)\n", argv[0]);
    fprintf(stderr, "%s in.fit[events][bin X,Y] out.fit  (bin an image) \n", argv[0]);
    fprintf(stderr, "%s in.fit[events][col x=.9*y] out.fit        (new x column)\n", argv[0]);
    fprintf(stderr, "%s in.fit[events][gtifilter()] out.fit       (time filter)\n", argv[0]);
    fprintf(stderr, "%s in.fit[2][regfilter(\"pow.reg\")] out.fit (spatial filter)\n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "Note that it may be necessary to enclose the input file name\n");
    fprintf(stderr, "in single quote characters on the Unix command line.\n");
    return (0);
  }

  /* Open the input file */
  if (!fits_open_file(&infptr, argv[1], READONLY, &status)) {
    /* Create the output file */
    if (!fits_create_file(&outfptr, argv[2], &status)) {
      /* Copy every HDU until we get an error */
      while (!fits_movabs_hdu(infptr, ii++, NULL, &status)) {
        fits_copy_hdu(infptr, outfptr, 0, &status);
      }

      /* Reset status after normal error */
      if (status == END_OF_FILE) {
        status = 0;
      }

      fits_close_file(outfptr,  &status);
    }
    fits_close_file(infptr, &status);
  }

  /* if error occured, print out error message */
  if (status) {
    fits_report_error(stderr, status);
  }
  return (status);
}
Beispiel #8
0
/* process this command */
static int ProcessCmd(char *cmd, char **args, int node, int tty)
{
  int ip=0;
  char tbuf[SZ_LINE];
  Finfo finfo, tfinfo;
#if HAVE_CFITSIO
  int x0, x1, y0, y1, bin;
  int xcolnum, ycolnum, hdunum, hdutype;
  int status=0, status2=0;
  int dims[2];
  double cens[2];
  char *cols[2] = {"X", "Y"};
  char *ofile=NULL;
  char *omode=NULL;
  fitsfile *ifptr, *ofptr, *tfptr;
#endif

  switch(*cmd){
  case 'f':
    if( !strcmp(cmd, "fitsFile") ){
      if( args && word(args[0], tbuf, &ip) ){
	if( !(tfinfo=FinfoLookup(tbuf)) ){
	  fprintf(stderr, NOIMAGE, tbuf);
	  return 1;
	}
      } else if( !(tfinfo=FinfoGetCurrent()) ){
	fprintf(stderr, NOFINFO, cmd);
	return 1;
      }
      if( tfinfo->fitsfile ){
	if( node ) fprintf(stdout, "fitsFile\r");
	fprintf(stdout, "%s %s\n", tfinfo->fname, tfinfo->fitsfile);
	fflush(stdout);
      }
      return 0;
    }
    break;
    break;
  case 'i':
    if( !strcmp(cmd, "image") ){
      if( !args || !word(args[0], tbuf, &ip) ){
	fprintf(stderr, WRONGARGS, cmd, 1, 0);
	return 1;
      }
      /* new image */
      if( !(finfo = FinfoNew(tbuf)) ){
	fprintf(stderr, NONEW, cmd);
	return 1;
      }
      /* make it current */
      FinfoSetCurrent(finfo);
      if( node ) fprintf(stdout, "image\r");
      /* return the FITS file name, if possible */
      fprintf(stdout, "%s %s\n",
	      finfo->fname, finfo->fitsfile ? finfo->fitsfile : "?");
      fflush(stdout);
      return 0;
    } else if( !strcmp(cmd, "image_") ){
      if( !args || !word(args[0], tbuf, &ip) ){
	fprintf(stderr, WRONGARGS, cmd, 1, 0);
	return 1;
      }
      /* new image */
      if( !(finfo = FinfoNew(tbuf)) ){
	fprintf(stderr, NONEW, cmd);
	return 1;
      }
      /* make it current */
      FinfoSetCurrent(finfo);
      /* no output! */
      return 0;
    } else if( !strcmp(cmd, "imsection") ){
#if HAVE_CFITSIO
      if( !(finfo=FinfoGetCurrent()) ){
	fprintf(stderr, NOFINFO, cmd);
	return 1;
      }
      ifptr = openFITSFile(finfo->fitsfile, EXTLIST, &hdutype, &status);
      if( status ){
	fprintf(stderr, "ERROR: can't open FITS file '%s'\n", finfo->fitsfile);
	return 1;
      }
      if( !args || !parseSection(args[0], &x0, &x1, &y0, &y1, &bin) ){
	fprintf(stderr,
		"ERROR: can't parse section for '%s' [%s]\n",
		finfo->fitsfile, (args && args[1]) ? args[1] : "NONE");
	return 1;
      }
      if( args[1] ){
	omode = args[1];
      } else {
	omode = "native";
      }
      ofile = "stdout";
      // create image if ifile is an image or omode is not native
      if( (hdutype == IMAGE_HDU) || strcmp(omode, "native") ){
	fits_create_file(&ofptr, ofile, &status);
	if( status ){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't open output FITS file to section '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  return 1;
	}
	switch(hdutype){
	case IMAGE_HDU:
	  if( bin != 1 ){
	    fprintf(stderr,
		    "ERROR: imsection of an image must use bin 1 for '%s'\n",
		    finfo->fitsfile);
	    return 1;
	  }
	  snprintf(tbuf, SZ_LINE-1, "%d:%d,%d:%d", x0, x1, y0, y1);
	  fits_copy_image_section(ifptr, ofptr, tbuf, &status);
	  break;
	default:
	  dims[0] = x1 - x0 + 1;
	  dims[1] = y1 - y0 + 1;
	  cens[0] = (x0 + x1) / 2;
	  cens[1] = (y0 + y1) / 2;
	  tfptr = filterTableToImage(ifptr, NULL, cols, dims, cens, bin,
				     &status);
	  if( status ){
	    fits_get_errstatus(status, tbuf);
	    fprintf(stderr,
		    "ERROR: can't create image from table for '%s' [%s]\n",
		    finfo->fitsfile, tbuf);
	    return 1;
	  }
	  fits_copy_image_section(tfptr, ofptr, "*,*", &status);
	  closeFITSFile(tfptr, &status2);
	  break;
	}
	if( status ){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't write section FITS file for '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  closeFITSFile(ofptr, &status);
	  return 1;
	}
	closeFITSFile(ofptr, &status);
      } else {
	// extract (native) table
	snprintf(tbuf, SZ_LINE-1,
		 "x >= %d && x <= %d && y >= %d && y <= %d",
		 x0, x1, y0, y1);
	// ffselect_table(&ifptr, ofile, tbuf, &status);
	// copied from cfileio.c/ffselect_table()
	/* create new empty file to hold copy of the image */
	if (ffinit(&ofptr, ofile, &status) > 0) {
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't init section file for '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  return 1;
	}
	/* save current HDU number in input file */
	fits_get_hdu_num(ifptr, &hdunum);
	/* copy the primary array */
	fits_movabs_hdu(ifptr, 1, NULL, &status);
	if( fits_copy_hdu(ifptr, ofptr, 0, &status) > 0){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't copy primary for section file '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  fits_close_file(ofptr, &status);
	  return 1;
	}
	/* back to current hdu */
	fits_movabs_hdu(ifptr, hdunum, NULL, &status);
	/* copy all the header keywords from the input to output file */
	if (fits_copy_header(ifptr, ofptr, &status) > 0){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't copy header for section file '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  fits_close_file(ofptr, &status);
	  return 1;
	}
	/* set number of rows = 0 */
	/* warning: start of cfitsio black magic */
	fits_modify_key_lng(ofptr, "NAXIS2", 0, NULL, &status);
	(ofptr->Fptr)->numrows = 0;
	(ofptr->Fptr)->origrows = 0;
	/* force the header to be scanned */
	if (ffrdef(ofptr, &status) > 0){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't rdef for section file '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  fits_close_file(ofptr, &status);
	  return 1;
	}
	/* warning: end of cfitsio black magic */
	/* select filtered rows and write to output file */
	if (fits_select_rows(ifptr, ofptr, tbuf, &status) > 0){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't select rows for section file '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  fits_close_file(ofptr, &status);
	  return 1;
	}
	/* update params for this section */
	if( (fits_get_colnum(ofptr, CASEINSEN, "X", &xcolnum, &status) > 0) ||
	    (fits_get_colnum(ofptr, CASEINSEN, "Y", &ycolnum, &status) > 0) ){
	  fits_get_errstatus(status, tbuf);
	  fprintf(stderr,
		  "ERROR: can't find X,Y cols for section file '%s' [%s]\n",
		  finfo->fitsfile, tbuf);
	  fits_close_file(ofptr, &status);
	  return 1;
	}
	/* we can ignore errors here */
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TALEN%d", xcolnum);
	fits_modify_key_lng(ofptr, tbuf, x1-x0, NULL, &status);
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TALEN%d", ycolnum);
	fits_modify_key_lng(ofptr, tbuf, y1-y0, NULL, &status);
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TLMIN%d", xcolnum);
	fits_modify_key_flt(ofptr, tbuf, x0, 6, NULL, &status);
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TLMAX%d", xcolnum);
	fits_modify_key_flt(ofptr, tbuf, x1, 6, NULL, &status);
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TLMIN%d", ycolnum);
	fits_modify_key_flt(ofptr, tbuf, y0, 6, NULL, &status);
	status = 0;
	snprintf(tbuf, SZ_LINE-1, "TLMAX%d", ycolnum);
	fits_modify_key_flt(ofptr, tbuf, y1, 6, NULL, &status);
	/* close the output file */
	status = 0;
	fits_close_file(ofptr, &status);
      }
      closeFITSFile(ifptr, &status);
      return 0;
#else
      fprintf(stderr,
	      "ERROR: for section support, build js9helper with cfitsio\n");
      return 1;
#endif
    } else if( !strcmp(cmd, "info") ){
      if( tty ){
	if( !(finfo=FinfoGetCurrent()) ){
	  fprintf(stderr, NOFINFO, cmd);
	  return 1;
	}
	/* make sure we have a wcs */
	fprintf(stdout, "fname:\t%s\n", finfo->fname);
	fprintf(stdout, "fits:\t%s\n", finfo->fitsfile?finfo->fitsfile:"N/A");
	fflush(stdout);
      }
      return 0;
    }
    break;
  case 'l':
    /* list all images */
    if( !strcmp(cmd, "list") ){
      FinfoList(stdout);
      return 0;
    }
    break;
  case 's':
    if( !strcmp(cmd, "setDataPath") ){
      if( args && word(args[0], tbuf, &ip) ){
	setenv("JS9_DATAPATH", tbuf, 1);
	if( node ) fprintf(stdout, "setDataPath\r");
	fprintf(stdout, "%s\n", getenv("JS9_DATAPATH"));
	fflush(stdout);
      } else {
	fprintf(stderr, WRONGARGS, cmd, 1, 0);
	return 1;
      }
      return 0;
    }
    break;
  case 'u':
    if( !strcmp(cmd, "unimage") ){
      if( !args || !word(args[0], tbuf, &ip) ){
	fprintf(stderr, WRONGARGS, cmd, 1, 0);
	return 1;
      }
      /* close this image */
      FinfoFree(tbuf);
      return 0;
    }
    break;
  case '#':
  case '\0':
    return 0;
  default:
    break;
  }
  /* if we reached here, we did not recognize the command */
  fprintf(stderr, "ERROR: unknown command '%s'\n", cmd);
  /* return the news */
  return 2;
}